--- a/jdk/make/sun/net/FILES_java.gmk Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/make/sun/net/FILES_java.gmk Tue Oct 23 11:29:53 2012 -0700
@@ -128,8 +128,6 @@
sun/net/www/content/audio/x_wav.java \
sun/net/www/protocol/ftp/Handler.java \
sun/net/www/protocol/ftp/FtpURLConnection.java \
- sun/net/www/protocol/gopher/GopherClient.java \
- sun/net/www/protocol/gopher/Handler.java \
sun/net/www/protocol/mailto/Handler.java \
sun/net/www/protocol/mailto/MailToURLConnection.java \
sun/net/idn/Punycode.java \
--- a/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/com/sun/beans/decoder/DocumentHandler.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,9 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
@@ -46,6 +49,8 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
+import sun.misc.SharedSecrets;
+
/**
* The main class to parse JavaBeans XML archive.
*
@@ -56,11 +61,10 @@
* @see ElementHandler
*/
public final class DocumentHandler extends DefaultHandler {
- private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>();
-
- private final Map<String, Object> environment = new HashMap<String, Object>();
-
- private final List<Object> objects = new ArrayList<Object>();
+ private final AccessControlContext acc = AccessController.getContext();
+ private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<>();
+ private final Map<String, Object> environment = new HashMap<>();
+ private final List<Object> objects = new ArrayList<>();
private Reference<ClassLoader> loader;
private ExceptionListener listener;
@@ -351,23 +355,32 @@
*
* @param input the input source to parse
*/
- public void parse(InputSource input) {
- try {
- SAXParserFactory.newInstance().newSAXParser().parse(input, this);
- }
- catch (ParserConfigurationException exception) {
- handleException(exception);
+ public void parse(final InputSource input) {
+ if ((this.acc == null) && (null != System.getSecurityManager())) {
+ throw new SecurityException("AccessControlContext is not set");
}
- catch (SAXException wrapper) {
- Exception exception = wrapper.getException();
- if (exception == null) {
- exception = wrapper;
+ AccessControlContext stack = AccessController.getContext();
+ SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this);
+ }
+ catch (ParserConfigurationException exception) {
+ handleException(exception);
+ }
+ catch (SAXException wrapper) {
+ Exception exception = wrapper.getException();
+ if (exception == null) {
+ exception = wrapper;
+ }
+ handleException(exception);
+ }
+ catch (IOException exception) {
+ handleException(exception);
+ }
+ return null;
}
- handleException(exception);
- }
- catch (IOException exception) {
- handleException(exception);
- }
+ }, stack, this.acc);
}
/**
--- a/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,8 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import sun.reflect.misc.MethodUtil;
+
/**
* This class is intended to handle <property> element.
* This element simplifies access to the properties.
@@ -168,11 +170,11 @@
private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
Class<?> type = bean.getClass();
if (index == null) {
- return findGetter(type, name).invoke(bean);
+ return MethodUtil.invoke(findGetter(type, name), bean, new Object[] {});
} else if (type.isArray() && (name == null)) {
return Array.get(bean, index);
} else {
- return findGetter(type, name, int.class).invoke(bean, index);
+ return MethodUtil.invoke(findGetter(type, name, int.class), bean, new Object[] {index});
}
}
@@ -197,11 +199,11 @@
: null;
if (index == null) {
- findSetter(type, name, param).invoke(bean, value);
+ MethodUtil.invoke(findSetter(type, name, param), bean, new Object[] {value});
} else if (type.isArray() && (name == null)) {
Array.set(bean, index, value);
} else {
- findSetter(type, name, int.class, param).invoke(bean, index, value);
+ MethodUtil.invoke(findSetter(type, name, int.class, param), bean, new Object[] {index, value});
}
}
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Tue Oct 23 11:29:53 2012 -0700
@@ -68,9 +68,9 @@
this.notifBuffer = notifBuffer;
this.connectionId = connectionId;
connectionTimeout = EnvHelp.getServerConnectionTimeout(env);
- checkNotificationEmission = EnvHelp.computeBooleanFromString(
- env,
- "jmx.remote.x.check.notification.emission",false);
+
+ String stringBoolean = (String) env.get("jmx.remote.x.check.notification.emission");
+ checkNotificationEmission = EnvHelp.computeBooleanFromString( stringBoolean );
notificationAccessController =
EnvHelp.getNotificationAccessController(env);
}
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Tue Oct 23 11:29:53 2012 -0700
@@ -665,97 +665,57 @@
* Computes a boolean value from a string value retrieved from a
* property in the given map.
*
- * @param env the environment map.
- * @param prop the name of the property in the environment map whose
- * returned string value must be converted into a boolean value.
- * @param systemProperty if true, consult a system property of the
- * same name if there is no entry in the environment map.
+ * @param stringBoolean the string value that must be converted
+ * into a boolean value.
*
* @return
* <ul>
- * <li>{@code false} if {@code env.get(prop)} is {@code null}</li>
+ * <li>{@code false} if {@code stringBoolean} is {@code null}</li>
* <li>{@code false} if
- * {@code ((String)env.get(prop)).equalsIgnoreCase("false")}
+ * {@code stringBoolean.equalsIgnoreCase("false")}
* is {@code true}</li>
* <li>{@code true} if
- * {@code ((String)env.get(prop)).equalsIgnoreCase("true")}
+ * {@code stringBoolean.equalsIgnoreCase("true")}
* is {@code true}</li>
* </ul>
*
- * @throws IllegalArgumentException if {@code env} is {@code null} or
- * {@code env.get(prop)} is not {@code null} and
+ * @throws IllegalArgumentException if
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are
* {@code false}.
- * @throws ClassCastException if {@code env.get(prop)} cannot be cast
- * to {@code String}.
*/
- public static boolean computeBooleanFromString(
- Map<String, ?> env, String prop, boolean systemProperty) {
-
- if (env == null)
- throw new IllegalArgumentException("env map cannot be null");
-
+ public static boolean computeBooleanFromString(String stringBoolean) {
// returns a default value of 'false' if no property is found...
- return computeBooleanFromString(env,prop,systemProperty,false);
+ return computeBooleanFromString(stringBoolean,false);
}
/**
* Computes a boolean value from a string value retrieved from a
* property in the given map.
*
- * @param env the environment map.
- * @param prop the name of the property in the environment map whose
- * returned string value must be converted into a boolean value.
- * @param systemProperty if true, consult a system property of the
- * same name if there is no entry in the environment map.
+ * @param stringBoolean the string value that must be converted
+ * into a boolean value.
* @param defaultValue a default value to return in case no property
* was defined.
*
* @return
* <ul>
- * <li>{@code defaultValue} if {@code env.get(prop)} is {@code null}
- * and {@code systemProperty} is {@code false}</li>
- * <li>{@code defaultValue} if {@code env.get(prop)} is {@code null}
- * and {@code systemProperty} is {@code true} and
- * {@code System.getProperty(prop)} is {@code null}</li>
- * <li>{@code false} if {@code env.get(prop)} is {@code null}
- * and {@code systemProperty} is {@code true} and
- * {@code System.getProperty(prop).equalsIgnoreCase("false")}
- * is {@code true}</li>
- * <li>{@code true} if {@code env.get(prop)} is {@code null}
- * and {@code systemProperty} is {@code true} and
- * {@code System.getProperty(prop).equalsIgnoreCase("true")}
- * is {@code true}</li>
+ * <li>{@code defaultValue} if {@code stringBoolean}
+ * is {@code null}</li>
* <li>{@code false} if
- * {@code ((String)env.get(prop)).equalsIgnoreCase("false")}
+ * {@code stringBoolean.equalsIgnoreCase("false")}
* is {@code true}</li>
* <li>{@code true} if
- * {@code ((String)env.get(prop)).equalsIgnoreCase("true")}
+ * {@code stringBoolean.equalsIgnoreCase("true")}
* is {@code true}</li>
* </ul>
*
- * @throws IllegalArgumentException if {@code env} is {@code null} or
- * {@code env.get(prop)} is not {@code null} and
+ * @throws IllegalArgumentException if
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are
* {@code false}.
- * @throws ClassCastException if {@code env.get(prop)} cannot be cast
- * to {@code String}.
*/
- public static boolean computeBooleanFromString(
- Map<String, ?> env, String prop,
- boolean systemProperty, boolean defaultValue) {
-
- if (env == null)
- throw new IllegalArgumentException("env map cannot be null");
-
- String stringBoolean = (String) env.get(prop);
- if (stringBoolean == null && systemProperty) {
- stringBoolean =
- AccessController.doPrivileged(new GetPropertyAction(prop));
- }
-
+ public static boolean computeBooleanFromString( String stringBoolean, boolean defaultValue) {
if (stringBoolean == null)
return defaultValue;
else if (stringBoolean.equalsIgnoreCase("true"))
@@ -763,8 +723,8 @@
else if (stringBoolean.equalsIgnoreCase("false"))
return false;
else
- throw new IllegalArgumentException(prop +
- " must be \"true\" or \"false\" instead of \"" +
+ throw new IllegalArgumentException(
+ "Property value must be \"true\" or \"false\" instead of \"" +
stringBoolean + "\"");
}
--- a/jdk/src/share/classes/java/beans/XMLDecoder.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/beans/XMLDecoder.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,9 @@
import java.io.Closeable;
import java.io.InputStream;
import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;
@@ -61,6 +64,7 @@
* @author Philip Milne
*/
public class XMLDecoder implements AutoCloseable {
+ private final AccessControlContext acc = AccessController.getContext();
private final DocumentHandler handler = new DocumentHandler();
private final InputSource input;
private Object owner;
@@ -189,7 +193,15 @@
return false;
}
if (this.array == null) {
- this.handler.parse(this.input);
+ if ((this.acc == null) && (null != System.getSecurityManager())) {
+ throw new SecurityException("AccessControlContext is not set");
+ }
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ XMLDecoder.this.handler.parse(XMLDecoder.this.input);
+ return null;
+ }
+ }, this.acc);
this.array = this.handler.getObjects();
}
return true;
--- a/jdk/src/share/classes/java/io/FilePermission.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/io/FilePermission.java Tue Oct 23 11:29:53 2012 -0700
@@ -407,7 +407,7 @@
* @return a hash code value for this object.
*/
public int hashCode() {
- return this.cpath.hashCode();
+ return 0;
}
/**
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,14 @@
package java.lang.invoke;
-import sun.invoke.util.VerifyType;
-
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import sun.invoke.empty.Empty;
import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.MethodHandleStatics.*;
@@ -781,4 +782,168 @@
return mh;
}
+ /**
+ * Create an alias for the method handle which, when called,
+ * appears to be called from the same class loader and protection domain
+ * as hostClass.
+ * This is an expensive no-op unless the method which is called
+ * is sensitive to its caller. A small number of system methods
+ * are in this category, including Class.forName and Method.invoke.
+ */
+ static
+ MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
+ return BindCaller.bindCaller(mh, hostClass);
+ }
+
+ // Put the whole mess into its own nested class.
+ // That way we can lazily load the code and set up the constants.
+ private static class BindCaller {
+ static
+ MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
+ // Do not use this function to inject calls into system classes.
+ if (hostClass == null) {
+ hostClass = C_Trampoline;
+ } else if (hostClass.isArray() ||
+ hostClass.isPrimitive() ||
+ hostClass.getName().startsWith("java.") ||
+ hostClass.getName().startsWith("sun.")) {
+ throw new InternalError(); // does not happen, and should not anyway
+ }
+ // For simplicity, convert mh to a varargs-like method.
+ MethodHandle vamh = prepareForInvoker(mh);
+ // Cache the result of makeInjectedInvoker once per argument class.
+ MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
+ return restoreToType(bccInvoker.bindTo(vamh), mh.type());
+ }
+
+ // This class ("Trampoline") is known to be inside a dead-end class loader.
+ // Inject all doubtful calls into this class.
+ private static Class<?> C_Trampoline;
+ static {
+ Class<?> tramp = null;
+ try {
+ final int FRAME_COUNT_ARG = 1; // [0] Reflection [1] Trampoline
+ java.lang.reflect.Method gcc = sun.reflect.Reflection.class.getMethod("getCallerClass", int.class);
+ tramp = (Class<?>) sun.reflect.misc.MethodUtil.invoke(gcc, null, new Object[]{ FRAME_COUNT_ARG });
+ if (tramp.getClassLoader() == BindCaller.class.getClassLoader())
+ throw new RuntimeException(tramp.getName()+" class loader");
+ } catch (Throwable ex) {
+ throw new InternalError(ex);
+ }
+ C_Trampoline = tramp;
+ }
+
+ private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
+ Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
+ if (hostClass.getClassLoader() != bcc.getClassLoader())
+ throw new InternalError(hostClass.getName()+" (CL)");
+ try {
+ if (hostClass.getProtectionDomain() != bcc.getProtectionDomain())
+ throw new InternalError(hostClass.getName()+" (PD)");
+ } catch (SecurityException ex) {
+ // Self-check was blocked by security manager. This is OK.
+ // In fact the whole try body could be turned into an assertion.
+ }
+ try {
+ MethodHandle init = IMPL_LOOKUP.findStatic(bcc, "init", MethodType.methodType(void.class));
+ init.invokeExact(); // force initialization of the class
+ } catch (Throwable ex) {
+ throw uncaughtException(ex);
+ }
+ MethodHandle bccInvoker;
+ try {
+ MethodType invokerMT = MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
+ bccInvoker = IMPL_LOOKUP.findStatic(bcc, "invoke_V", invokerMT);
+ } catch (ReflectiveOperationException ex) {
+ throw uncaughtException(ex);
+ }
+ // Test the invoker, to ensure that it really injects into the right place.
+ try {
+ MethodHandle vamh = prepareForInvoker(MH_checkCallerClass);
+ Object ok = bccInvoker.invokeExact(vamh, new Object[]{hostClass, bcc});
+ } catch (Throwable ex) {
+ throw new InternalError(ex);
+ }
+ return bccInvoker;
+ }
+ private static ClassValue<MethodHandle> CV_makeInjectedInvoker = new ClassValue<MethodHandle>() {
+ @Override protected MethodHandle computeValue(Class<?> hostClass) {
+ return makeInjectedInvoker(hostClass);
+ }
+ };
+
+ // Adapt mh so that it can be called directly from an injected invoker:
+ private static MethodHandle prepareForInvoker(MethodHandle mh) {
+ mh = mh.asFixedArity();
+ MethodType mt = mh.type();
+ int arity = mt.parameterCount();
+ MethodHandle vamh = mh.asType(mt.generic());
+ vamh.internalForm().compileToBytecode(); // eliminate LFI stack frames
+ vamh = vamh.asSpreader(Object[].class, arity);
+ vamh.internalForm().compileToBytecode(); // eliminate LFI stack frames
+ return vamh;
+ }
+
+ // Undo the adapter effect of prepareForInvoker:
+ private static MethodHandle restoreToType(MethodHandle vamh, MethodType type) {
+ return vamh.asCollector(Object[].class, type.parameterCount()).asType(type);
+ }
+
+ private static final MethodHandle MH_checkCallerClass;
+ static {
+ final Class<?> THIS_CLASS = BindCaller.class;
+ assert(checkCallerClass(THIS_CLASS, THIS_CLASS));
+ try {
+ MH_checkCallerClass = IMPL_LOOKUP
+ .findStatic(THIS_CLASS, "checkCallerClass",
+ MethodType.methodType(boolean.class, Class.class, Class.class));
+ assert((boolean) MH_checkCallerClass.invokeExact(THIS_CLASS, THIS_CLASS));
+ } catch (Throwable ex) {
+ throw new InternalError(ex);
+ }
+ }
+
+ private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
+ final int FRAME_COUNT_ARG = 2; // [0] Reflection [1] BindCaller [2] Expected
+ Class<?> actual = sun.reflect.Reflection.getCallerClass(FRAME_COUNT_ARG);
+ if (actual != expected && actual != expected2)
+ throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
+ +(expected == expected2 ? "" : ", or else "+expected2.getName()));
+ return true;
+ }
+
+ private static final byte[] T_BYTES;
+ static {
+ final Object[] values = {null};
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ Class<T> tClass = T.class;
+ String tName = tClass.getName();
+ String tResource = tName.substring(tName.lastIndexOf('.')+1)+".class";
+ java.net.URLConnection uconn = tClass.getResource(tResource).openConnection();
+ int len = uconn.getContentLength();
+ byte[] bytes = new byte[len];
+ try (java.io.InputStream str = uconn.getInputStream()) {
+ int nr = str.read(bytes);
+ if (nr != len) throw new java.io.IOException(tResource);
+ }
+ values[0] = bytes;
+ } catch (java.io.IOException ex) {
+ throw new InternalError(ex);
+ }
+ return null;
+ }
+ });
+ T_BYTES = (byte[]) values[0];
+ }
+
+ // The following class is used as a template for Unsafe.defineAnonymousClass:
+ private static class T {
+ static void init() { } // side effect: initializes this class
+ static Object invoke_V(MethodHandle vamh, Object[] args) throws Throwable {
+ return vamh.invokeExact(args);
+ }
+ }
+ }
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Tue Oct 23 11:29:53 2012 -0700
@@ -385,4 +385,101 @@
throw err;
}
}
+
+ /**
+ * Is this method a caller-sensitive method?
+ * I.e., does it call Reflection.getCallerClass or a similer method
+ * to ask about the identity of its caller?
+ */
+ // FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
+ static boolean isCallerSensitive(MemberName mem) {
+ assert(mem.isInvocable());
+ Class<?> defc = mem.getDeclaringClass();
+ switch (mem.getName()) {
+ case "doPrivileged":
+ return defc == java.security.AccessController.class;
+ case "getUnsafe":
+ return defc == sun.misc.Unsafe.class;
+ case "lookup":
+ return defc == java.lang.invoke.MethodHandles.class;
+ case "invoke":
+ return defc == java.lang.reflect.Method.class;
+ case "get":
+ case "getBoolean":
+ case "getByte":
+ case "getChar":
+ case "getShort":
+ case "getInt":
+ case "getLong":
+ case "getFloat":
+ case "getDouble":
+ case "set":
+ case "setBoolean":
+ case "setByte":
+ case "setChar":
+ case "setShort":
+ case "setInt":
+ case "setLong":
+ case "setFloat":
+ case "setDouble":
+ return defc == java.lang.reflect.Field.class;
+ case "newInstance":
+ if (defc == java.lang.reflect.Constructor.class) return true;
+ if (defc == java.lang.Class.class) return true;
+ break;
+ case "forName":
+ case "getClassLoader":
+ case "getClasses":
+ case "getFields":
+ case "getMethods":
+ case "getConstructors":
+ case "getDeclaredClasses":
+ case "getDeclaredFields":
+ case "getDeclaredMethods":
+ case "getDeclaredConstructors":
+ case "getField":
+ case "getMethod":
+ case "getConstructor":
+ case "getDeclaredField":
+ case "getDeclaredMethod":
+ case "getDeclaredConstructor":
+ return defc == java.lang.Class.class;
+ case "getConnection":
+ case "getDriver":
+ case "getDrivers":
+ case "deregisterDriver":
+ return defc == java.sql.DriverManager.class;
+ case "newUpdater":
+ if (defc == java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class) return true;
+ if (defc == java.util.concurrent.atomic.AtomicLongFieldUpdater.class) return true;
+ if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
+ break;
+ case "getContextClassLoader":
+ return defc == java.lang.Thread.class;
+ case "getPackage":
+ case "getPackages":
+ return defc == java.lang.Package.class;
+ case "getParent":
+ case "getSystemClassLoader":
+ return defc == java.lang.ClassLoader.class;
+ case "load":
+ case "loadLibrary":
+ if (defc == java.lang.Runtime.class) return true;
+ if (defc == java.lang.System.class) return true;
+ break;
+ case "getCallerClass":
+ if (defc == sun.reflect.Reflection.class) return true;
+ if (defc == java.lang.System.class) return true;
+ break;
+ case "getCallerClassLoader":
+ return defc == java.lang.ClassLoader.class;
+ case "getProxyClass":
+ case "newProxyInstance":
+ return defc == java.lang.reflect.Proxy.class;
+ case "getBundle":
+ case "clearCache":
+ return defc == java.util.ResourceBundle.class;
+ }
+ return false;
+ }
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -108,7 +108,7 @@
/*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
return new IllegalArgumentException(message(message, obj, obj2));
}
- /*non-public*/ static Error uncaughtException(Exception ex) {
+ /*non-public*/ static Error uncaughtException(Throwable ex) {
throw new InternalError("uncaught exception", ex);
}
static Error NYI() {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -329,6 +329,7 @@
* where {@code defcPkg} is the package of {@code defc}.
* </ul>
*/
+ // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle
public static final
class Lookup {
/** The class on behalf of whom the lookup is being performed. */
@@ -1209,6 +1210,7 @@
if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method);
MethodHandle mh = DirectMethodHandle.make(refc, method);
+ mh = maybeBindCaller(method, mh);
mh = mh.setVarargs(method);
if (doRestrict)
mh = restrictReceiver(method, mh, lookupClass());
@@ -1217,6 +1219,16 @@
private MethodHandle fakeMethodHandleInvoke(MemberName method) {
return throwException(method.getReturnType(), UnsupportedOperationException.class);
}
+ private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh) throws IllegalAccessException {
+ if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
+ return mh;
+ Class<?> hostClass = lookupClass;
+ if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup
+ hostClass = null;
+ MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
+ // Note: caller will apply varargs after this step happens.
+ return cbmh;
+ }
private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
checkField(refKind, refc, field);
MethodHandle mh = DirectMethodHandle.make(refc, field);
@@ -1229,6 +1241,7 @@
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
assert(ctor.isConstructor());
checkAccess(REF_newInvokeSpecial, refc, ctor);
+ assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
return DirectMethodHandle.make(ctor).setVarargs(ctor);
}
--- a/jdk/src/share/classes/java/security/AccessController.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/security/AccessController.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -290,11 +290,11 @@
*/
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
- DomainCombiner dc = null;
AccessControlContext acc = getStackAccessControlContext();
- if (acc == null || (dc = acc.getAssignedCombiner()) == null) {
+ if (acc == null) {
return AccessController.doPrivileged(action);
}
+ DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc));
}
@@ -386,11 +386,11 @@
public static <T> T doPrivilegedWithCombiner
(PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
- DomainCombiner dc = null;
AccessControlContext acc = getStackAccessControlContext();
- if (acc == null || (dc = acc.getAssignedCombiner()) == null) {
+ if (acc == null) {
return AccessController.doPrivileged(action);
}
+ DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc));
}
@@ -417,7 +417,12 @@
// perform 'combine' on the caller of doPrivileged,
// even if the caller is from the bootclasspath
ProtectionDomain[] pds = new ProtectionDomain[] {callerPd};
- return new AccessControlContext(combiner.combine(pds, null), combiner);
+ if (combiner == null) {
+ return new AccessControlContext(pds);
+ } else {
+ return new AccessControlContext(combiner.combine(pds, null),
+ combiner);
+ }
}
--- a/jdk/src/share/classes/java/util/ServiceLoader.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/ServiceLoader.java Tue Oct 23 11:29:53 2012 -0700
@@ -358,14 +358,21 @@
}
String cn = nextName;
nextName = null;
+ Class<?> c = null;
try {
- S p = service.cast(Class.forName(cn, true, loader)
- .newInstance());
- providers.put(cn, p);
- return p;
+ c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
+ }
+ if (!service.isAssignableFrom(c)) {
+ fail(service,
+ "Provider " + cn + " not a subtype");
+ }
+ try {
+ S p = service.cast(c.newInstance());
+ providers.put(cn, p);
+ return p;
} catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated: " + x,
--- a/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Oct 23 11:29:53 2012 -0700
@@ -530,18 +530,17 @@
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
- ClassLoader savedcl = null;
Thread t = Thread.currentThread();
- try {
- ClassLoader cl = t.getContextClassLoader();
- if (ccl != cl) {
- t.setContextClassLoader(ccl);
- savedcl = cl;
+ ClassLoader cl = t.getContextClassLoader();
+ if (ccl == cl) {
+ return task.call();
+ } else {
+ t.setContextClassLoader(ccl);
+ try {
+ return task.call();
+ } finally {
+ t.setContextClassLoader(cl);
}
- return task.call();
- } finally {
- if (savedcl != null)
- t.setContextClassLoader(savedcl);
}
}
}, acc);
--- a/jdk/src/share/classes/java/util/logging/FileHandler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java Tue Oct 23 11:29:53 2012 -0700
@@ -220,7 +220,7 @@
* @exception NullPointerException if pattern property is an empty String.
*/
public FileHandler() throws IOException, SecurityException {
- checkAccess();
+ checkPermission();
configure();
openFiles();
}
@@ -246,7 +246,7 @@
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
- checkAccess();
+ checkPermission();
configure();
this.pattern = pattern;
this.limit = 0;
@@ -278,7 +278,7 @@
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
- checkAccess();
+ checkPermission();
configure();
this.pattern = pattern;
this.limit = 0;
@@ -315,7 +315,7 @@
if (limit < 0 || count < 1 || pattern.length() < 1) {
throw new IllegalArgumentException();
}
- checkAccess();
+ checkPermission();
configure();
this.pattern = pattern;
this.limit = limit;
@@ -354,7 +354,7 @@
if (limit < 0 || count < 1 || pattern.length() < 1) {
throw new IllegalArgumentException();
}
- checkAccess();
+ checkPermission();
configure();
this.pattern = pattern;
this.limit = limit;
@@ -367,7 +367,7 @@
// configured instance variables.
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
- manager.checkAccess();
+ manager.checkPermission();
if (count < 1) {
throw new IllegalArgumentException("file count = " + count);
}
--- a/jdk/src/share/classes/java/util/logging/Handler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/Handler.java Tue Oct 23 11:29:53 2012 -0700
@@ -111,7 +111,7 @@
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
public void setFormatter(Formatter newFormatter) throws SecurityException {
- checkAccess();
+ checkPermission();
// Check for a null pointer:
newFormatter.getClass();
formatter = newFormatter;
@@ -140,7 +140,7 @@
*/
public void setEncoding(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
- checkAccess();
+ checkPermission();
if (encoding != null) {
try {
if(!java.nio.charset.Charset.isSupported(encoding)) {
@@ -175,7 +175,7 @@
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
public void setFilter(Filter newFilter) throws SecurityException {
- checkAccess();
+ checkPermission();
filter = newFilter;
}
@@ -199,7 +199,7 @@
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
public void setErrorManager(ErrorManager em) {
- checkAccess();
+ checkPermission();
if (em == null) {
throw new NullPointerException();
}
@@ -213,7 +213,7 @@
* the caller does not have <tt>LoggingPermission("control")</tt>.
*/
public ErrorManager getErrorManager() {
- checkAccess();
+ checkPermission();
return errorManager;
}
@@ -253,7 +253,7 @@
if (newLevel == null) {
throw new NullPointerException();
}
- checkAccess();
+ checkPermission();
logLevel = newLevel;
}
@@ -296,9 +296,9 @@
// If "sealed" is true, we check that the caller has
// appropriate security privileges to update Handler
// state and if not throw a SecurityException.
- void checkAccess() throws SecurityException {
+ void checkPermission() throws SecurityException {
if (sealed) {
- manager.checkAccess();
+ manager.checkPermission();
}
}
}
--- a/jdk/src/share/classes/java/util/logging/LogManager.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java Tue Oct 23 11:29:53 2012 -0700
@@ -321,7 +321,7 @@
@Deprecated
public void addPropertyChangeListener(PropertyChangeListener l) throws SecurityException {
PropertyChangeListener listener = Objects.requireNonNull(l);
- checkAccess();
+ checkPermission();
synchronized (listenerMap) {
// increment the registration count if already registered
Integer value = listenerMap.get(listener);
@@ -352,7 +352,7 @@
*/
@Deprecated
public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException {
- checkAccess();
+ checkPermission();
if (l != null) {
PropertyChangeListener listener = l;
synchronized (listenerMap) {
@@ -807,7 +807,7 @@
* @exception IOException if there are IO problems reading the configuration.
*/
public void readConfiguration() throws IOException, SecurityException {
- checkAccess();
+ checkPermission();
// if a configuration class is specified, load it and use it.
String cname = System.getProperty("java.util.logging.config.class");
@@ -865,7 +865,7 @@
*/
public void reset() throws SecurityException {
- checkAccess();
+ checkPermission();
synchronized (this) {
props = new Properties();
// Since we are doing a reset we no longer want to initialize
@@ -950,7 +950,7 @@
* @exception IOException if there are problems reading from the stream.
*/
public void readConfiguration(InputStream ins) throws IOException, SecurityException {
- checkAccess();
+ checkPermission();
reset();
// Load the properties
@@ -1127,8 +1127,13 @@
loadLoggerHandlers(rootLogger, null, "handlers");
}
+ private final Permission controlPermission = new LoggingPermission("control", null);
- private Permission ourPermission = new LoggingPermission("control", null);
+ void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(controlPermission);
+ }
/**
* Check that the current context is trusted to modify the logging
@@ -1141,11 +1146,7 @@
* the caller does not have LoggingPermission("control").
*/
public void checkAccess() throws SecurityException {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- return;
- }
- sm.checkPermission(ourPermission);
+ checkPermission();
}
// Nested class to represent a node in our tree of named loggers.
--- a/jdk/src/share/classes/java/util/logging/Logger.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/Logger.java Tue Oct 23 11:29:53 2012 -0700
@@ -276,13 +276,13 @@
this.manager = manager;
}
- private void checkAccess() throws SecurityException {
+ private void checkPermission() throws SecurityException {
if (!anonymous) {
if (manager == null) {
// Complete initialization of the global Logger.
manager = LogManager.getLogManager();
}
- manager.checkAccess();
+ manager.checkPermission();
}
}
@@ -482,7 +482,7 @@
* the caller does not have LoggingPermission("control").
*/
public void setFilter(Filter newFilter) throws SecurityException {
- checkAccess();
+ checkPermission();
filter = newFilter;
}
@@ -1168,7 +1168,7 @@
* the caller does not have LoggingPermission("control").
*/
public void setLevel(Level newLevel) throws SecurityException {
- checkAccess();
+ checkPermission();
synchronized (treeLock) {
levelObject = newLevel;
updateEffectiveLevel();
@@ -1223,7 +1223,7 @@
public void addHandler(Handler handler) throws SecurityException {
// Check for null handler
handler.getClass();
- checkAccess();
+ checkPermission();
handlers.add(handler);
}
@@ -1237,7 +1237,7 @@
* the caller does not have LoggingPermission("control").
*/
public void removeHandler(Handler handler) throws SecurityException {
- checkAccess();
+ checkPermission();
if (handler == null) {
return;
}
@@ -1265,7 +1265,7 @@
* the caller does not have LoggingPermission("control").
*/
public void setUseParentHandlers(boolean useParentHandlers) {
- checkAccess();
+ checkPermission();
this.useParentHandlers = useParentHandlers;
}
@@ -1420,7 +1420,7 @@
if (parent == null) {
throw new NullPointerException();
}
- manager.checkAccess();
+ manager.checkPermission();
doSetParent(parent);
}
--- a/jdk/src/share/classes/java/util/logging/MemoryHandler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/MemoryHandler.java Tue Oct 23 11:29:53 2012 -0700
@@ -238,7 +238,7 @@
throw new NullPointerException();
}
LogManager manager = LogManager.getLogManager();
- checkAccess();
+ checkPermission();
pushLevel = newLevel;
}
--- a/jdk/src/share/classes/java/util/logging/StreamHandler.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/java/util/logging/StreamHandler.java Tue Oct 23 11:29:53 2012 -0700
@@ -249,7 +249,7 @@
}
private synchronized void flushAndClose() throws SecurityException {
- checkAccess();
+ checkPermission();
if (writer != null) {
try {
if (!doneHeader) {
--- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Tue Oct 23 11:29:53 2012 -0700
@@ -1245,13 +1245,12 @@
return s.substring(1, s.length() - 1);
}
final String className = s.substring(1, slash);
+
final Constructor<?> constr;
try {
+ ReflectUtil.checkPackageAccess(className);
final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
- if (contextClassLoader == null) {
- ReflectUtil.checkPackageAccess(className);
- }
final Class<?> c =
Class.forName(className, false, contextClassLoader);
constr = c.getConstructor(new Class<?>[] {String.class});
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,30 @@
package javax.management.remote.rmi;
+import java.io.IOException;
+import java.rmi.MarshalledObject;
+import java.rmi.UnmarshalException;
+import java.rmi.server.Unreferenced;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.*;
+import javax.management.remote.JMXServerErrorException;
+import javax.management.remote.NotificationResult;
+import javax.management.remote.TargetedNotification;
+import javax.security.auth.Subject;
+
import static com.sun.jmx.mbeanserver.Util.cast;
import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
import com.sun.jmx.remote.internal.ServerNotifForwarder;
@@ -35,44 +59,6 @@
import com.sun.jmx.remote.util.EnvHelp;
import com.sun.jmx.remote.util.OrderClassLoaders;
-import java.io.IOException;
-import java.rmi.MarshalledObject;
-import java.rmi.UnmarshalException;
-import java.rmi.server.Unreferenced;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.RuntimeOperationsException;
-import javax.management.remote.JMXServerErrorException;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.TargetedNotification;
-import javax.security.auth.Subject;
-
/**
* <p>Implementation of the {@link RMIConnection} interface. User
* code will not usually reference this class.</p>
@@ -143,6 +129,7 @@
this.mbeanServer = rmiServer.getMBeanServer();
final ClassLoader dcl = defaultClassLoader;
+
this.classLoaderWithRepository =
AccessController.doPrivileged(
new PrivilegedAction<ClassLoaderWithRepository>() {
@@ -151,13 +138,40 @@
mbeanServer.getClassLoaderRepository(),
dcl);
}
+ },
+
+ withPermissions( new MBeanPermission("*", "getClassLoaderRepository"),
+ new RuntimePermission("createClassLoader"))
+ );
+
+
+ this.defaultContextClassLoader =
+ AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
+ dcl);
+ }
});
+
serverCommunicatorAdmin = new
RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
this.env = env;
}
+ private static AccessControlContext withPermissions(Permission ... perms){
+ Permissions col = new Permissions();
+
+ for (Permission thePerm : perms ) {
+ col.add(thePerm);
+ }
+
+ final ProtectionDomain pd = new ProtectionDomain(null, col);
+ return new AccessControlContext( new ProtectionDomain[] { pd });
+ }
+
private synchronized ServerNotifForwarder getServerNotifFwd() {
// Lazily created when first use. Mainly when
// addNotificationListener is first called.
@@ -507,7 +521,7 @@
"connectionId=" + connectionId
+" unwrapping query with defaultClassLoader.");
- queryValue = unwrap(query, defaultClassLoader, QueryExp.class);
+ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class);
try {
final Object params[] = new Object[] { name, queryValue };
@@ -542,7 +556,7 @@
"connectionId=" + connectionId
+" unwrapping query with defaultClassLoader.");
- queryValue = unwrap(query, defaultClassLoader, QueryExp.class);
+ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class);
try {
final Object params[] = new Object[] { name, queryValue };
@@ -1330,7 +1344,9 @@
public ClassLoader run() throws InstanceNotFoundException {
return mbeanServer.getClassLoader(name);
}
- });
+ },
+ withPermissions(new MBeanPermission("*", "getClassLoader"))
+ );
} catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe);
}
@@ -1345,7 +1361,9 @@
public Object run() throws InstanceNotFoundException {
return mbeanServer.getClassLoaderFor(name);
}
- });
+ },
+ withPermissions(new MBeanPermission("*", "getClassLoaderFor"))
+ );
} catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe);
}
@@ -1572,7 +1590,8 @@
ClassLoader orderCL = AccessController.doPrivileged(
new PrivilegedExceptionAction<ClassLoader>() {
public ClassLoader run() throws Exception {
- return new OrderClassLoaders(cl1, cl2);
+ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
+ new OrderClassLoaders(cl1, cl2));
}
}
);
@@ -1664,6 +1683,8 @@
private final ClassLoader defaultClassLoader;
+ private final ClassLoader defaultContextClassLoader;
+
private final ClassLoaderWithRepository classLoaderWithRepository;
private boolean terminated = false;
@@ -1746,4 +1767,43 @@
private static final ClassLogger logger =
new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl");
+
+ private static final class CombinedClassLoader extends ClassLoader {
+
+ private final static class ClassLoaderWrapper extends ClassLoader {
+ ClassLoaderWrapper(ClassLoader cl) {
+ super(cl);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ return super.loadClass(name, resolve);
+ }
+ };
+
+ final ClassLoaderWrapper defaultCL;
+
+ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) {
+ super(parent);
+ this.defaultCL = new ClassLoaderWrapper(defaultCL);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ try {
+ super.loadClass(name, resolve);
+ } catch(Exception e) {
+ for(Throwable t = e; t != null; t = t.getCause()) {
+ if(t instanceof SecurityException) {
+ throw t==e?(SecurityException)t:new SecurityException(t.getMessage(), e);
+ }
+ }
+ }
+ final Class<?> cl = defaultCL.loadClass(name, resolve);
+ return cl;
+ }
+
+ }
}
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Tue Oct 23 11:29:53 2012 -0700
@@ -277,9 +277,9 @@
// Check for secure RMIServer stub if the corresponding
// client-side environment property is set to "true".
//
- boolean checkStub = EnvHelp.computeBooleanFromString(
- usemap,
- "jmx.remote.x.check.stub",false);
+ String stringBoolean = (String) usemap.get("jmx.remote.x.check.stub");
+ boolean checkStub = EnvHelp.computeBooleanFromString(stringBoolean);
+
if (checkStub) checkStub(stub, rmiServerImplStubClass);
// Connect IIOP Stub if needed.
--- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Tue Oct 23 11:29:53 2012 -0700
@@ -412,9 +412,8 @@
if (tracing)
logger.trace("start", "Using external directory: " + jndiUrl);
- final boolean rebind = EnvHelp.computeBooleanFromString(
- attributes,
- JNDI_REBIND_ATTRIBUTE,false);
+ String stringBoolean = (String) attributes.get(JNDI_REBIND_ATTRIBUTE);
+ final boolean rebind = EnvHelp.computeBooleanFromString( stringBoolean );
if (tracing)
logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);
--- a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java Tue Oct 23 11:29:53 2012 -0700
@@ -24,6 +24,8 @@
*/
package javax.swing.text;
+import sun.reflect.misc.ConstructorUtil;
+
import java.io.Serializable;
import java.lang.reflect.*;
import java.text.ParseException;
@@ -245,7 +247,7 @@
Constructor cons;
try {
- cons = vc.getConstructor(new Class[] { String.class });
+ cons = ConstructorUtil.getConstructor(vc, new Class[]{String.class});
} catch (NoSuchMethodException nsme) {
cons = null;
--- a/jdk/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/invoke/anon/AnonymousClassLoader.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,74 +73,14 @@
public class AnonymousClassLoader {
final Class<?> hostClass;
- // Note: Do not refactor the calls to checkHostClass unless you
- // also adjust this constant:
- private static int CHC_CALLERS = 3;
-
- public AnonymousClassLoader() {
- this.hostClass = checkHostClass(null);
- }
- public AnonymousClassLoader(Class<?> hostClass) {
- this.hostClass = checkHostClass(hostClass);
- }
-
- private static Class<?> getTopLevelClass(Class<?> clazz) {
- for(Class<?> outer = clazz.getDeclaringClass(); outer != null;
- outer = outer.getDeclaringClass()) {
- clazz = outer;
- }
- return clazz;
+ // Privileged constructor.
+ private AnonymousClassLoader(Class<?> hostClass) {
+ this.hostClass = hostClass;
}
- private static Class<?> checkHostClass(Class<?> hostClass) {
- // called only from the constructor
- // does a context-sensitive check on caller class
- // CC[0..3] = {Reflection, this.checkHostClass, this.<init>, caller}
- Class<?> caller = sun.reflect.Reflection.getCallerClass(CHC_CALLERS);
-
- if (caller == null) {
- // called from the JVM directly
- if (hostClass == null)
- return AnonymousClassLoader.class; // anything central will do
- return hostClass;
- }
-
- if (hostClass == null)
- hostClass = caller; // default value is caller itself
-
- // anonymous class will access hostClass on behalf of caller
- Class<?> callee = hostClass;
-
- if (caller == callee)
- // caller can always nominate itself to grant caller's own access rights
- return hostClass;
-
- // normalize caller and callee to their top-level classes:
- caller = getTopLevelClass(caller);
- callee = getTopLevelClass(callee);
- if (caller == callee)
- return caller;
-
- ClassLoader callerCL = caller.getClassLoader();
- if (callerCL == null) {
- // caller is trusted code, so accept the proposed hostClass
- return hostClass;
- }
-
- // %%% should do something with doPrivileged, because trusted
- // code should have a way to execute on behalf of
- // partially-trusted clients
-
- // Does the caller have the right to access the private
- // members of the callee? If not, raise an error.
- final int ACC_PRIVATE = 2;
- try {
- sun.reflect.Reflection.ensureMemberAccess(caller, callee, null, ACC_PRIVATE);
- } catch (IllegalAccessException ee) {
- throw new IllegalArgumentException(ee);
- }
-
- return hostClass;
+ public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class<?> hostClass) {
+ if (unsafe == null) throw new NullPointerException();
+ return new AnonymousClassLoader(hostClass);
}
public Class<?> loadClass(byte[] classFile) {
@@ -249,7 +189,7 @@
private static int fakeNameCounter = 99999;
// ignore two warnings on this line:
- static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ private static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
// preceding line requires that this class be on the boot class path
static private final Method defineAnonymousClass;
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -522,13 +522,19 @@
static {
MethodHandle mh = null;
try {
- java.lang.reflect.Method m = MethodHandles.class
+ final java.lang.reflect.Method m = MethodHandles.class
.getDeclaredMethod("collectArguments",
MethodHandle.class, int.class, MethodHandle.class);
- m.setAccessible(true);
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ m.setAccessible(true);
+ return null;
+ }
+ });
mh = IMPL_LOOKUP.unreflect(m);
- } catch (ReflectiveOperationException | SecurityException ex) {
+ } catch (ReflectiveOperationException ex) {
throw new InternalError(ex);
}
COLLECT_ARGUMENTS = mh;
--- a/jdk/src/share/classes/sun/misc/Service.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/misc/Service.java Tue Oct 23 11:29:53 2012 -0700
@@ -284,12 +284,20 @@
}
String cn = nextName;
nextName = null;
+ Class<?> c = null;
try {
- return service.cast(Class.forName(cn, true, loader).newInstance());
+ c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
- } catch (Exception x) {
+ }
+ if (!service.isAssignableFrom(c)) {
+ fail(service,
+ "Provider " + cn + " not a subtype");
+ }
+ try {
+ return service.cast(c.newInstance());
+ } catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated: " + x,
x);
--- a/jdk/src/share/classes/sun/net/www/protocol/gopher/GopherClient.java Tue Oct 23 09:41:52 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
-/*
- * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.net.www.protocol.gopher;
-
-import java.io.*;
-import java.util.*;
-import java.net.*;
-import sun.net.www.*;
-import sun.net.NetworkClient;
-import java.net.URL;
-import java.net.URLStreamHandler;
-
-import sun.security.action.GetBooleanAction;
-
-/** Class to maintain the state of a gopher fetch and handle the protocol */
-public class GopherClient extends NetworkClient implements Runnable {
-
- /* The following three data members are left in for binary
- * backwards-compatibility. Unfortunately, HotJava sets them directly
- * when it wants to change the settings. The new design has us not
- * cache these, so this is unnecessary, but eliminating the data members
- * would break HJB 1.1 under JDK 1.2.
- *
- * These data members are not used, and their values are meaningless.
- * REMIND: Take them out for JDK 2.0!
- */
-
- /**
- * @deprecated
- */
- @Deprecated
- public static boolean useGopherProxy;
-
- /**
- * @deprecated
- */
- @Deprecated
- public static String gopherProxyHost;
-
- /**
- * @deprecated
- */
- @Deprecated
- public static int gopherProxyPort;
-
-
- static {
- useGopherProxy = java.security.AccessController.doPrivileged(
- new sun.security.action.GetBooleanAction("gopherProxySet"))
- .booleanValue();
-
- gopherProxyHost = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("gopherProxyHost"));
-
- gopherProxyPort = java.security.AccessController.doPrivileged(
- new sun.security.action.GetIntegerAction("gopherProxyPort", 80))
- .intValue();
- }
-
- PipedOutputStream os;
- URL u;
- int gtype;
- String gkey;
- sun.net.www.URLConnection connection;
-
- GopherClient(sun.net.www.URLConnection connection) {
- this.connection = connection;
- }
-
- /**
- * @return true if gopher connections should go through a proxy, according
- * to system properties.
- */
- public static boolean getUseGopherProxy() {
- return java.security.AccessController.doPrivileged(
- new GetBooleanAction("gopherProxySet")).booleanValue();
- }
-
- /**
- * @return the proxy host to use, or null if nothing is set.
- */
- public static String getGopherProxyHost() {
- String host = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("gopherProxyHost"));
- if ("".equals(host)) {
- host = null;
- }
- return host;
- }
-
- /**
- * @return the proxy port to use. Will default reasonably.
- */
- public static int getGopherProxyPort() {
- return java.security.AccessController.doPrivileged(
- new sun.security.action.GetIntegerAction("gopherProxyPort", 80))
- .intValue();
- }
-
- /** Given a url, setup to fetch the gopher document it refers to */
- InputStream openStream(URL u) throws IOException {
- this.u = u;
- this.os = os;
- int i = 0;
- String s = u.getFile();
- int limit = s.length();
- int c = '1';
- while (i < limit && (c = s.charAt(i)) == '/')
- i++;
- gtype = c == '/' ? '1' : c;
- if (i < limit)
- i++;
- gkey = s.substring(i);
-
- openServer(u.getHost(), u.getPort() <= 0 ? 70 : u.getPort());
-
- MessageHeader msgh = new MessageHeader();
-
- switch (gtype) {
- case '0':
- case '7':
- msgh.add("content-type", "text/plain");
- break;
- case '1':
- msgh.add("content-type", "text/html");
- break;
- case 'g':
- case 'I':
- msgh.add("content-type", "image/gif");
- break;
- default:
- msgh.add("content-type", "content/unknown");
- break;
- }
- if (gtype != '7') {
- serverOutput.print(decodePercent(gkey) + "\r\n");
- serverOutput.flush();
- } else if ((i = gkey.indexOf('?')) >= 0) {
- serverOutput.print(decodePercent(gkey.substring(0, i) + "\t" +
- gkey.substring(i + 1) + "\r\n"));
- serverOutput.flush();
- msgh.add("content-type", "text/html");
- } else {
- msgh.add("content-type", "text/html");
- }
- connection.setProperties(msgh);
- if (msgh.findValue("content-type") == "text/html") {
- os = new PipedOutputStream();
- PipedInputStream ret = new PipedInputStream();
- ret.connect(os);
- new Thread(this).start();
- return ret;
- }
- return new GopherInputStream(this, serverInput);
- }
-
- /** Translate all the instances of %NN into the character they represent */
- private String decodePercent(String s) {
- if (s == null || s.indexOf('%') < 0)
- return s;
- int limit = s.length();
- char d[] = new char[limit];
- int dp = 0;
- for (int sp = 0; sp < limit; sp++) {
- int c = s.charAt(sp);
- if (c == '%' && sp + 2 < limit) {
- int s1 = s.charAt(sp + 1);
- int s2 = s.charAt(sp + 2);
- if ('0' <= s1 && s1 <= '9')
- s1 = s1 - '0';
- else if ('a' <= s1 && s1 <= 'f')
- s1 = s1 - 'a' + 10;
- else if ('A' <= s1 && s1 <= 'F')
- s1 = s1 - 'A' + 10;
- else
- s1 = -1;
- if ('0' <= s2 && s2 <= '9')
- s2 = s2 - '0';
- else if ('a' <= s2 && s2 <= 'f')
- s2 = s2 - 'a' + 10;
- else if ('A' <= s2 && s2 <= 'F')
- s2 = s2 - 'A' + 10;
- else
- s2 = -1;
- if (s1 >= 0 && s2 >= 0) {
- c = (s1 << 4) | s2;
- sp += 2;
- }
- }
- d[dp++] = (char) c;
- }
- return new String(d, 0, dp);
- }
-
- /** Turn special characters into the %NN form */
- private String encodePercent(String s) {
- if (s == null)
- return s;
- int limit = s.length();
- char d[] = null;
- int dp = 0;
- for (int sp = 0; sp < limit; sp++) {
- int c = s.charAt(sp);
- if (c <= ' ' || c == '"' || c == '%') {
- if (d == null)
- d = s.toCharArray();
- if (dp + 3 >= d.length) {
- char nd[] = new char[dp + 10];
- System.arraycopy(d, 0, nd, 0, dp);
- d = nd;
- }
- d[dp] = '%';
- int dig = (c >> 4) & 0xF;
- d[dp + 1] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig);
- dig = c & 0xF;
- d[dp + 2] = (char) (dig < 10 ? '0' + dig : 'A' - 10 + dig);
- dp += 3;
- } else {
- if (d != null) {
- if (dp >= d.length) {
- char nd[] = new char[dp + 10];
- System.arraycopy(d, 0, nd, 0, dp);
- d = nd;
- }
- d[dp] = (char) c;
- }
- dp++;
- }
- }
- return d == null ? s : new String(d, 0, dp);
- }
-
- /** This method is run as a seperate thread when an incoming gopher
- document requires translation to html */
- public void run() {
- int qpos = -1;
- try {
- if (gtype == '7' && (qpos = gkey.indexOf('?')) < 0) {
- PrintStream ps = new PrintStream(os, false, encoding);
- ps.print("<html><head><title>Searchable Gopher Index</title></head>\n<body><h1>Searchable Gopher Index</h1><isindex>\n</body></html>\n");
- } else if (gtype != '1' && gtype != '7') {
- byte buf[] = new byte[2048];
- try {
- int n;
- while ((n = serverInput.read(buf)) >= 0)
- os.write(buf, 0, n);
- } catch(Exception e) {
- }
- } else {
- PrintStream ps = new PrintStream(os, false, encoding);
- String title = null;
- if (gtype == '7')
- title = "Results of searching for \"" + gkey.substring(qpos + 1)
- + "\" on " + u.getHost();
- else
- title = "Gopher directory " + gkey + " from " + u.getHost();
- ps.print("<html><head><title>");
- ps.print(title);
- ps.print("</title></head>\n<body>\n<H1>");
- ps.print(title);
- ps.print("</h1><dl compact>\n");
- BufferedReader ds = new BufferedReader(new InputStreamReader(serverInput));
- String s;
- while ((s = ds.readLine()) != null) {
- int len = s.length();
- while (len > 0 && s.charAt(len - 1) <= ' ')
- len--;
- if (len <= 0)
- continue;
- int key = s.charAt(0);
- int t1 = s.indexOf('\t');
- int t2 = t1 > 0 ? s.indexOf('\t', t1 + 1) : -1;
- int t3 = t2 > 0 ? s.indexOf('\t', t2 + 1) : -1;
- if (t3 < 0) {
- // ps.print("<br><i>"+s+"</i>\n");
- continue;
- }
- String port = t3 + 1 < len ? ":" + s.substring(t3 + 1, len) : "";
- String host = t2 + 1 < t3 ? s.substring(t2 + 1, t3) : u.getHost();
- ps.print("<dt><a href=\"gopher://" + host + port + "/"
- + s.substring(0, 1) + encodePercent(s.substring(t1 + 1, t2)) + "\">\n");
- ps.print("<img align=middle border=0 width=25 height=32 src=");
- switch (key) {
- default:
- ps.print(System.getProperty("java.net.ftp.imagepath.file"));
- break;
- case '0':
- ps.print(System.getProperty("java.net.ftp.imagepath.text"));
- break;
- case '1':
- ps.print(System.getProperty("java.net.ftp.imagepath.directory"));
- break;
- case 'g':
- ps.print(System.getProperty("java.net.ftp.imagepath.gif"));
- break;
- }
- ps.print(".gif align=middle><dd>\n");
- ps.print(s.substring(1, t1) + "</a>\n");
- }
- ps.print("</dl></body>\n");
- ps.close();
- }
-
- } catch (UnsupportedEncodingException e) {
- throw new InternalError(encoding+ " encoding not found", e);
- } catch (IOException e) {
- } finally {
- try {
- closeServer();
- os.close();
- } catch (IOException e2) {
- }
- }
- }
-}
-
-/** An input stream that does nothing more than hold on to the NetworkClient
- that created it. This is used when only the input stream is needed, and
- the network client needs to be closed when the input stream is closed. */
-class GopherInputStream extends FilterInputStream {
- NetworkClient parent;
-
- GopherInputStream(NetworkClient o, InputStream fd) {
- super(fd);
- parent = o;
- }
-
- public void close() {
- try {
- parent.closeServer();
- super.close();
- } catch (IOException e) {
- }
- }
-}
--- a/jdk/src/share/classes/sun/net/www/protocol/gopher/Handler.java Tue Oct 23 09:41:52 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net.www.protocol.gopher;
-
-import java.io.*;
-import java.util.*;
-import sun.net.NetworkClient;
-import java.net.URL;
-import java.net.URLStreamHandler;
-import java.net.Proxy;
-import java.net.InetSocketAddress;
-import java.net.SocketPermission;
-import java.security.Permission;
-import sun.net.www.protocol.http.HttpURLConnection;
-
-/**
- * A class to handle the gopher protocol.
- */
-
-public class Handler extends java.net.URLStreamHandler {
-
- protected int getDefaultPort() {
- return 70;
- }
-
- public java.net.URLConnection openConnection(URL u)
- throws IOException {
- return openConnection(u, null);
- }
-
- public java.net.URLConnection openConnection(URL u, Proxy p)
- throws IOException {
-
-
- /* if set for proxy usage then go through the http code to get */
- /* the url connection. */
- if (p == null && GopherClient.getUseGopherProxy()) {
- String host = GopherClient.getGopherProxyHost();
- if (host != null) {
- InetSocketAddress saddr = InetSocketAddress.createUnresolved(host, GopherClient.getGopherProxyPort());
-
- p = new Proxy(Proxy.Type.HTTP, saddr);
- }
- }
- if (p != null) {
- return new HttpURLConnection(u, p);
- }
-
- return new GopherURLConnection(u);
- }
-}
-
-class GopherURLConnection extends sun.net.www.URLConnection {
-
- Permission permission;
-
- GopherURLConnection(URL u) {
- super(u);
- }
-
- public void connect() throws IOException {
- }
-
- public InputStream getInputStream() throws IOException {
- return new GopherClient(this).openStream(url);
- }
-
- public Permission getPermission() {
- if (permission == null) {
- int port = url.getPort();
- port = port < 0 ? 70 : port;
- String host = url.getHost() + ":" + url.getPort();
- permission = new SocketPermission(host, "connect");
- }
- return permission;
- }
-}
--- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java Tue Oct 23 11:29:53 2012 -0700
@@ -405,7 +405,8 @@
*/
perms.add(new SocketPermission("*", "connect,accept"));
- perms.add(new RuntimePermission("accessClassInPackage.sun.*"));
+ perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*"));
+ perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*"));
perms.add(new FilePermission("<<ALL FILES>>", "read"));
--- a/jdk/src/share/classes/sun/security/provider/SecureRandom.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/security/provider/SecureRandom.java Tue Oct 23 11:29:53 2012 -0700
@@ -56,12 +56,6 @@
private static final long serialVersionUID = 3581829991155417889L;
- /**
- * This static object will be seeded by SeedGenerator, and used
- * to seed future instances of SecureRandom
- */
- private static SecureRandom seeder;
-
private static final int DIGEST_SIZE = 20;
private transient MessageDigest digest;
private byte[] state;
@@ -173,6 +167,28 @@
}
/**
+ * This static object will be seeded by SeedGenerator, and used
+ * to seed future instances of SHA1PRNG SecureRandoms.
+ *
+ * Bloch, Effective Java Second Edition: Item 71
+ */
+ private static class SeederHolder {
+
+ private static final SecureRandom seeder;
+
+ static {
+ /*
+ * Call to SeedGenerator.generateSeed() to add additional
+ * seed material (likely from the Native implementation).
+ */
+ seeder = new SecureRandom(SeedGenerator.getSystemEntropy());
+ byte [] b = new byte[DIGEST_SIZE];
+ SeedGenerator.generateSeed(b);
+ seeder.engineSetSeed(b);
+ }
+ }
+
+ /**
* Generates a user-specified number of random bytes.
*
* @param bytes the array to be filled in with random bytes.
@@ -183,13 +199,8 @@
byte[] output = remainder;
if (state == null) {
- if (seeder == null) {
- seeder = new SecureRandom(SeedGenerator.getSystemEntropy());
- seeder.engineSetSeed(engineGenerateSeed(DIGEST_SIZE));
- }
-
byte[] seed = new byte[DIGEST_SIZE];
- seeder.engineNextBytes(seed);
+ SeederHolder.seeder.engineNextBytes(seed);
state = digest.digest(seed);
}
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java Tue Oct 23 11:29:53 2012 -0700
@@ -191,6 +191,7 @@
byte[] getBytes8() throws IOException {
int len = getInt8();
+ verifyLength(len);
byte b[] = new byte[len];
read(b, 0, len);
@@ -199,6 +200,7 @@
public byte[] getBytes16() throws IOException {
int len = getInt16();
+ verifyLength(len);
byte b[] = new byte[len];
read(b, 0, len);
@@ -207,10 +209,19 @@
byte[] getBytes24() throws IOException {
int len = getInt24();
+ verifyLength(len);
byte b[] = new byte[len];
read(b, 0, len);
return b;
}
+ // Is a length greater than available bytes in the record?
+ private void verifyLength(int len) throws SSLException {
+ if (len > available()) {
+ throw new SSLException(
+ "Not enough data to fill declared vector size");
+ }
+ }
+
}
--- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java Tue Oct 23 11:29:53 2012 -0700
@@ -1079,7 +1079,6 @@
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out);
- System.out.println("Generating new random premaster secret");
}
if (requestedVersion != null) {
@@ -1146,7 +1145,6 @@
System.out.println("RSA PreMasterSecret version error: expected"
+ protocolVersion + " or " + requestedVersion + ", decrypted: "
+ premasterVersion);
- System.out.println("Generating new random premaster secret");
}
preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion);
--- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Oct 23 11:29:53 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
import javax.net.ssl.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+import sun.security.util.KeyLength;
/**
* This is the client key exchange message (CLIENT --> SERVER) used with
@@ -192,26 +193,38 @@
"unable to get the plaintext of the premaster secret");
}
- // We are not always able to get the encoded key of the
- // premaster secret. Pass the cheking to master secret
+ int keySize = KeyLength.getKeySize(secretKey);
+ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "incorrect length of premaster secret: " +
+ (keySize/8));
+ }
+
+ return generateDummySecret(clientHelloVersion);
+ }
+
+ // The key size is exactly 48 bytes or not accessible.
+ //
+ // Conservatively, pass the checking to master secret
// calculation.
return secretKey;
} else if (encoded.length == 48) {
// check the version
if (clientHelloVersion.major == encoded[0] &&
clientHelloVersion.minor == encoded[1]) {
+
return secretKey;
- } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v) {
+ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
+ currentVersion.major == encoded[0] &&
+ currentVersion.minor == encoded[1]) {
/*
- * we never checked the client_version in server side
- * for TLS v1.0 and SSL v3.0. For compatibility, we
- * maintain this behavior.
+ * For compatibility, we maintain the behavior that the
+ * version in pre_master_secret can be the negotiated
+ * version for TLS v1.0 and SSL v3.0.
*/
- if (currentVersion.major == encoded[0] &&
- currentVersion.minor == encoded[1]) {
- this.protocolVersion = currentVersion;
- return secretKey;
- }
+ this.protocolVersion = currentVersion;
+ return secretKey;
}
if (debug != null && Debug.isOn("handshake")) {
@@ -220,22 +233,23 @@
", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1]));
}
+
+ return generateDummySecret(clientHelloVersion);
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"incorrect length of premaster secret: " +
encoded.length);
}
+
+ return generateDummySecret(clientHelloVersion);
}
}
- if (debug != null && Debug.isOn("handshake")) {
- if (failoverException != null) {
- System.out.println("Error decrypting premaster secret:");
- failoverException.printStackTrace(System.out);
- }
-
- System.out.println("Generating random secret");
+ if (debug != null && Debug.isOn("handshake") &&
+ failoverException != null) {
+ System.out.println("Error decrypting premaster secret:");
+ failoverException.printStackTrace(System.out);
}
return generateDummySecret(clientHelloVersion);
@@ -243,6 +257,10 @@
// generate a premaster secret with the specified version number
static SecretKey generateDummySecret(ProtocolVersion version) {
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println("Generating a random fake premaster secret");
+ }
+
try {
String s = ((version.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
--- a/jdk/src/share/lib/security/java.security Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/lib/security/java.security Tue Oct 23 11:29:53 2012 -0700
@@ -145,7 +145,7 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -157,7 +157,7 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-macosx Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/lib/security/java.security-macosx Tue Oct 23 11:29:53 2012 -0700
@@ -146,7 +146,7 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -158,7 +158,7 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-solaris Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/lib/security/java.security-solaris Tue Oct 23 11:29:53 2012 -0700
@@ -147,7 +147,7 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -159,7 +159,7 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# Determines whether this properties file can be appended to
--- a/jdk/src/share/lib/security/java.security-windows Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/src/share/lib/security/java.security-windows Tue Oct 23 11:29:53 2012 -0700
@@ -146,7 +146,7 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# List of comma-separated packages that start with or equal this string
@@ -158,7 +158,7 @@
# by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition.
#
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,jdk.internal.
+package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
#
# Determines whether this properties file can be appended to
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/7196190/ClassForNameTest.java Tue Oct 23 11:29:53 2012 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7196190
+ * @summary Improve method of handling MethodHandles
+ *
+ * @run main/othervm ClassForNameTest
+ */
+
+import java.lang.invoke.*;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+public class ClassForNameTest {
+ final static String NAME = ClassForNameTest.class.getName();
+
+ public static void main(String[] args) throws Throwable {
+ {
+ final MethodType mt = MethodType.methodType(Class.class, String.class);
+ final MethodHandle mh = MethodHandles.lookup()
+ .findStatic(Class.class, "forName", mt);
+
+ Class.forName(NAME);
+
+ mh.invoke(NAME);
+ mh.bindTo(NAME).invoke();
+ mh.invokeWithArguments(Arrays.asList(NAME));
+ mh.invokeWithArguments(NAME);
+ Class cls = (Class) mh.invokeExact(NAME);
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodType mt = MethodType.methodType(Object.class, Object.class, Object[].class);
+ final MethodHandle mh = MethodHandles.lookup()
+ .findVirtual(Method.class, "invoke", mt)
+ .bindTo(fnMethod);
+
+ fnMethod.invoke(null, NAME);
+
+ mh.bindTo(null).bindTo(new Object[]{NAME}).invoke();
+ mh.invoke(null, new Object[]{NAME});
+ mh.invokeWithArguments(null, new Object[]{NAME});
+ mh.invokeWithArguments(Arrays.asList(null, new Object[]{NAME}));
+ Object obj = mh.invokeExact((Object) null, new Object[]{NAME});
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodType mt = MethodType.methodType(Object.class, Object.class, Object[].class);
+
+ final MethodHandle mh = MethodHandles.lookup()
+ .bind(fnMethod, "invoke", mt);
+
+ mh.bindTo(null).bindTo(new Object[]{NAME}).invoke();
+ mh.invoke(null, new Object[]{NAME});
+ mh.invokeWithArguments(null, NAME);
+ mh.invokeWithArguments(Arrays.asList(null, NAME));
+ Object obj = mh.invokeExact((Object) null, new Object[]{NAME});
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodHandle mh = MethodHandles.lookup().unreflect(fnMethod);
+
+ mh.bindTo(NAME).invoke();
+ mh.invoke(NAME);
+ mh.invokeWithArguments(NAME);
+ mh.invokeWithArguments(Arrays.asList(NAME));
+ Class cls = (Class) mh.invokeExact(NAME);
+ }
+
+ System.out.println("TEST PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/7196190/GetUnsafeTest.java Tue Oct 23 11:29:53 2012 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7196190
+ * @summary Improve method of handling MethodHandles
+ *
+ * @run main/othervm/policy=jtreg.security.policy/secure=java.lang.SecurityManager GetUnsafeTest
+ */
+
+import java.lang.invoke.*;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+public class GetUnsafeTest {
+ final static String NAME = "sun.misc.Unsafe";
+
+ private static boolean isTestFailed = false;
+
+ private static void fail() {
+ isTestFailed = true;
+ try { throw new Exception(); } catch (Throwable e) {
+ StackTraceElement frame = e.getStackTrace()[1];
+ System.out.printf("Failed at %s:%d\n", frame.getFileName(), frame.getLineNumber());
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ {
+ final MethodType mt = MethodType.methodType(Class.class, String.class);
+ final MethodHandle mh = MethodHandles.lookup()
+ .findStatic(Class.class, "forName", mt);
+
+ try { Class.forName(NAME); fail(); } catch (Throwable e) {}
+
+ try { mh.invoke(NAME); fail(); } catch (Throwable e) {}
+ try { mh.bindTo(NAME).invoke(); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(Arrays.asList(NAME)); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(NAME); fail(); } catch (Throwable e) {}
+ try { Class cls = (Class) mh.invokeExact(NAME); fail(); } catch (Throwable e) {}
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodType mt = MethodType.methodType(Object.class, Object.class, Object[].class);
+ final MethodHandle mh = MethodHandles.lookup()
+ .findVirtual(Method.class, "invoke", mt)
+ .bindTo(fnMethod);
+
+ try { fnMethod.invoke(null, NAME); fail(); } catch (Throwable e) {}
+
+ try { mh.bindTo(null).bindTo(new Object[]{NAME}).invoke(); fail(); } catch (Throwable e) {}
+ try { mh.invoke(null, new Object[]{NAME}); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(null, new Object[]{NAME}); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(Arrays.asList(null, new Object[]{NAME})); fail(); } catch (Throwable e) {}
+ try { Object obj = mh.invokeExact((Object) null, new Object[]{NAME}); fail(); } catch (Throwable e) {}
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodType mt = MethodType.methodType(Object.class, Object.class, Object[].class);
+
+ final MethodHandle mh = MethodHandles.lookup().bind(fnMethod, "invoke", mt);
+
+ try { mh.bindTo(null).bindTo(new Object[]{NAME}).invoke(); fail(); } catch (Throwable e) {}
+ try { mh.invoke(null, new Object[]{NAME}); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(null, NAME); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(Arrays.asList(null, NAME)); fail(); } catch (Throwable e) {}
+ try { Object obj = mh.invokeExact((Object) null, new Object[]{NAME}); fail(); } catch (Throwable e) {}
+ }
+
+ {
+ final Method fnMethod = Class.class.getMethod("forName", String.class);
+ final MethodHandle mh = MethodHandles.lookup().unreflect(fnMethod);
+
+ try { mh.bindTo(NAME).invoke(); fail(); } catch (Throwable e) {}
+ try { mh.invoke(NAME); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(NAME); fail(); } catch (Throwable e) {}
+ try { mh.invokeWithArguments(Arrays.asList(NAME)); fail(); } catch (Throwable e) {}
+ try { Class cls = (Class) mh.invokeExact(NAME); fail(); } catch (Throwable e) {}
+ }
+
+ if (!isTestFailed) {
+ System.out.println("TEST PASSED");
+ } else {
+ System.out.println("TEST FAILED");
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/7196190/MHProxyTest.java Tue Oct 23 11:29:53 2012 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7196190
+ * @summary Improve method of handling MethodHandles
+ *
+ * @run main/othervm MHProxyTest
+ */
+
+import java.lang.invoke.*;
+import java.security.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class MHProxyTest {
+ private static final Class<?> C_Unsafe;
+ private static final MethodHandle MH_getUnsafe;
+ static {
+ // Do these before there is a SM installed.
+ C_Unsafe = sun.misc.Unsafe.class; // EXPECT A WARNING ON THIS LINE
+ Lookup lookup = lookup();
+ MethodHandle gumh = null;
+ try {
+ gumh = lookup.findStatic(C_Unsafe, "getUnsafe", methodType(C_Unsafe));
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError(ex.toString());
+ }
+ MH_getUnsafe = gumh;
+ // Try some different lookups:
+ try {
+ lookup.in(Object.class).findStatic(C_Unsafe, "getUnsafe", methodType(C_Unsafe));
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError(ex.toString());
+ }
+ lookup = lookup().in(C_Unsafe);
+ try {
+ lookup.in(C_Unsafe).findStatic(C_Unsafe, "getUnsafe", methodType(C_Unsafe));
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError(ex.toString());
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ System.setSecurityManager(new SecurityManager());
+ Lookup lookup = lookup();
+ testBasic(lookup);
+ testDoPriv(lookup);
+ testSetVar();
+ Lookup l2 = lookup.in(Object.class);
+ System.out.println("=== "+l2);
+ testBasic(l2);
+ testDoPriv(l2);
+ Lookup l3 = lookup.in(C_Unsafe);
+ System.out.println("=== "+l3);
+ testBasic(l3);
+ testDoPriv(l3);
+ if (failure != null)
+ throw failure;
+ }
+
+ private static Throwable failure;
+ private static void fail(Throwable ex) {
+ if (failure == null)
+ failure = ex;
+ StackTraceElement frame = new Exception().getStackTrace()[1];
+ System.out.printf("Failed at %s:%d: %s\n", frame.getFileName(), frame.getLineNumber(), ex);
+ }
+ private static void ok(Throwable ex) {
+ StackTraceElement frame = new Exception().getStackTrace()[1];
+ System.out.printf("OK at %s:%d: %s\n", frame.getFileName(), frame.getLineNumber(), ex);
+ }
+
+ private static void testBasic(Lookup lookup) throws Throwable {
+ // Verify that we can't get to this guy under the SM:
+ try {
+ MethodHandle badmh = lookup.findStatic(C_Unsafe, "getUnsafe", methodType(C_Unsafe));
+ assert(badmh.type() == methodType(C_Unsafe));
+ badmh = badmh.asType(badmh.type().generic());
+ Object u = C_Unsafe.cast(badmh.invokeExact());
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got mh to getUnsafe!"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ try {
+ Object u = MH_getUnsafe.invokeWithArguments();
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got the Unsafe object! (MH invoke)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ try {
+ MethodHandle mh = MH_getUnsafe;
+ mh = mh.asType(mh.type().generic());
+ mh = foldArguments(identity(Object.class), mh);
+ mh = filterReturnValue(mh, identity(Object.class));
+ Object u = mh.invokeExact();
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got the Unsafe object! (MH invokeWithArguments)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ }
+
+ private static void testDoPriv(Lookup lookup) throws Throwable {
+ PrivilegedAction privAct = MethodHandleProxies.asInterfaceInstance(PrivilegedAction.class, MH_getUnsafe);
+ try {
+ Object u = AccessController.doPrivileged(privAct);
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got the Unsafe object! (static doPriv)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ MethodHandle MH_doPriv = lookup.findStatic(AccessController.class, "doPrivileged",
+ methodType(Object.class, PrivilegedAction.class));
+ MH_doPriv = MH_doPriv.bindTo(privAct);
+ try {
+ Object u = MH_doPriv.invoke();
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got the Unsafe object! (MH + doPriv)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ // try one more layer of indirection:
+ Runnable rbl = MethodHandleProxies.asInterfaceInstance(Runnable.class, MH_doPriv);
+ try {
+ rbl.run();
+ fail(new AssertionError("got the Unsafe object! (Runnable + MH + doPriv)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ }
+
+ private static void testSetVar() throws Throwable {
+ {
+ // Test the box pattern:
+ Object[] box = new Object[1];
+ MethodHandle MH_getFoo = identity(Object.class).bindTo("foo");
+ MethodHandle MH_storeToBox = insertArguments(arrayElementSetter(Object[].class), 0, box, 0);
+ MethodHandle mh = filterReturnValue(MH_getFoo, MH_storeToBox);
+ mh.invokeExact();
+ assert(box[0] == "foo");
+ }
+ {
+ Object[] box = new Object[1];
+ MethodHandle MH_storeToBox = insertArguments(arrayElementSetter(Object[].class), 0, box, 0);
+ MethodHandle mh = filterReturnValue(MH_getUnsafe.asType(MH_getUnsafe.type().generic()), MH_storeToBox);
+ try {
+ mh.invokeExact();
+ Object u = box[0];
+ assert(C_Unsafe.isInstance(u));
+ fail(new AssertionError("got the Unsafe object! (MH + setElement)"));
+ } catch (SecurityException ex) {
+ ok(ex);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/7196190/jtreg.security.policy Tue Oct 23 11:29:53 2012 -0700
@@ -0,0 +1,9 @@
+/*
+ * security policy used by the test process
+ * must allow file reads so that jtreg itself can run
+ */
+
+grant {
+ // standard test activation permissions
+ permission java.io.FilePermission "*", "read";
+};
--- a/jdk/test/java/net/URL/Test.java Tue Oct 23 09:41:52 2012 -0700
+++ b/jdk/test/java/net/URL/Test.java Tue Oct 23 11:29:53 2012 -0700
@@ -322,10 +322,6 @@
test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
.s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z();
- test("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles")
- .s("gopher").h("spinaltap.micro.umn.edu")
- .p("/00/Weather/California/Los%20Angeles").z();
-
test("http://www.math.uio.no/faq/compression-faq/part1.html")
.s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z();