This commit is contained in:
Lana Steuck 2012-10-23 11:29:53 -07:00
commit 736ab82961
44 changed files with 1048 additions and 784 deletions

View File

@ -128,8 +128,6 @@ FILES_java = \
sun/net/www/content/audio/x_wav.java \ sun/net/www/content/audio/x_wav.java \
sun/net/www/protocol/ftp/Handler.java \ sun/net/www/protocol/ftp/Handler.java \
sun/net/www/protocol/ftp/FtpURLConnection.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/Handler.java \
sun/net/www/protocol/mailto/MailToURLConnection.java \ sun/net/www/protocol/mailto/MailToURLConnection.java \
sun/net/idn/Punycode.java \ sun/net/idn/Punycode.java \

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,9 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
@ -46,6 +49,8 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import sun.misc.SharedSecrets;
/** /**
* The main class to parse JavaBeans XML archive. * The main class to parse JavaBeans XML archive.
* *
@ -56,11 +61,10 @@ import org.xml.sax.helpers.DefaultHandler;
* @see ElementHandler * @see ElementHandler
*/ */
public final class DocumentHandler extends DefaultHandler { public final class DocumentHandler extends DefaultHandler {
private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>(); private final AccessControlContext acc = AccessController.getContext();
private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<>();
private final Map<String, Object> environment = new HashMap<String, Object>(); private final Map<String, Object> environment = new HashMap<>();
private final List<Object> objects = new ArrayList<>();
private final List<Object> objects = new ArrayList<Object>();
private Reference<ClassLoader> loader; private Reference<ClassLoader> loader;
private ExceptionListener listener; private ExceptionListener listener;
@ -351,23 +355,32 @@ public final class DocumentHandler extends DefaultHandler {
* *
* @param input the input source to parse * @param input the input source to parse
*/ */
public void parse(InputSource input) { public void parse(final InputSource input) {
try { if ((this.acc == null) && (null != System.getSecurityManager())) {
SAXParserFactory.newInstance().newSAXParser().parse(input, this); throw new SecurityException("AccessControlContext is not set");
} }
catch (ParserConfigurationException exception) { AccessControlContext stack = AccessController.getContext();
handleException(exception); SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Void>() {
} public Void run() {
catch (SAXException wrapper) { try {
Exception exception = wrapper.getException(); SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this);
if (exception == null) { }
exception = wrapper; 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); }, stack, this.acc);
}
catch (IOException exception) {
handleException(exception);
}
} }
/** /**

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,6 +35,8 @@ import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import sun.reflect.misc.MethodUtil;
/** /**
* This class is intended to handle &lt;property&gt; element. * This class is intended to handle &lt;property&gt; element.
* This element simplifies access to the properties. * This element simplifies access to the properties.
@ -168,11 +170,11 @@ final class PropertyElementHandler extends AccessorElementHandler {
private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException { private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
Class<?> type = bean.getClass(); Class<?> type = bean.getClass();
if (index == null) { if (index == null) {
return findGetter(type, name).invoke(bean); return MethodUtil.invoke(findGetter(type, name), bean, new Object[] {});
} else if (type.isArray() && (name == null)) { } else if (type.isArray() && (name == null)) {
return Array.get(bean, index); return Array.get(bean, index);
} else { } 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 @@ final class PropertyElementHandler extends AccessorElementHandler {
: null; : null;
if (index == 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)) { } else if (type.isArray() && (name == null)) {
Array.set(bean, index, value); Array.set(bean, index, value);
} else { } else {
findSetter(type, name, int.class, param).invoke(bean, index, value); MethodUtil.invoke(findSetter(type, name, int.class, param), bean, new Object[] {index, value});
} }
} }

View File

@ -68,9 +68,9 @@ public class ServerNotifForwarder {
this.notifBuffer = notifBuffer; this.notifBuffer = notifBuffer;
this.connectionId = connectionId; this.connectionId = connectionId;
connectionTimeout = EnvHelp.getServerConnectionTimeout(env); connectionTimeout = EnvHelp.getServerConnectionTimeout(env);
checkNotificationEmission = EnvHelp.computeBooleanFromString(
env, String stringBoolean = (String) env.get("jmx.remote.x.check.notification.emission");
"jmx.remote.x.check.notification.emission",false); checkNotificationEmission = EnvHelp.computeBooleanFromString( stringBoolean );
notificationAccessController = notificationAccessController =
EnvHelp.getNotificationAccessController(env); EnvHelp.getNotificationAccessController(env);
} }

View File

@ -665,97 +665,57 @@ public class EnvHelp {
* Computes a boolean value from a string value retrieved from a * Computes a boolean value from a string value retrieved from a
* property in the given map. * property in the given map.
* *
* @param env the environment map. * @param stringBoolean the string value that must be converted
* @param prop the name of the property in the environment map whose * into a boolean value.
* 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.
* *
* @return * @return
* <ul> * <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 * <li>{@code false} if
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} * {@code stringBoolean.equalsIgnoreCase("false")}
* is {@code true}</li> * is {@code true}</li>
* <li>{@code true} if * <li>{@code true} if
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} * {@code stringBoolean.equalsIgnoreCase("true")}
* is {@code true}</li> * is {@code true}</li>
* </ul> * </ul>
* *
* @throws IllegalArgumentException if {@code env} is {@code null} or * @throws IllegalArgumentException if
* {@code env.get(prop)} is not {@code null} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and * {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are * {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are
* {@code false}. * {@code false}.
* @throws ClassCastException if {@code env.get(prop)} cannot be cast
* to {@code String}.
*/ */
public static boolean computeBooleanFromString( public static boolean computeBooleanFromString(String stringBoolean) {
Map<String, ?> env, String prop, boolean systemProperty) {
if (env == null)
throw new IllegalArgumentException("env map cannot be null");
// returns a default value of 'false' if no property is found... // 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 * Computes a boolean value from a string value retrieved from a
* property in the given map. * property in the given map.
* *
* @param env the environment map. * @param stringBoolean the string value that must be converted
* @param prop the name of the property in the environment map whose * into a boolean value.
* 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 defaultValue a default value to return in case no property * @param defaultValue a default value to return in case no property
* was defined. * was defined.
* *
* @return * @return
* <ul> * <ul>
* <li>{@code defaultValue} if {@code env.get(prop)} is {@code null} * <li>{@code defaultValue} if {@code stringBoolean}
* and {@code systemProperty} is {@code false}</li> * is {@code null}</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 false} if * <li>{@code false} if
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} * {@code stringBoolean.equalsIgnoreCase("false")}
* is {@code true}</li> * is {@code true}</li>
* <li>{@code true} if * <li>{@code true} if
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} * {@code stringBoolean.equalsIgnoreCase("true")}
* is {@code true}</li> * is {@code true}</li>
* </ul> * </ul>
* *
* @throws IllegalArgumentException if {@code env} is {@code null} or * @throws IllegalArgumentException if
* {@code env.get(prop)} is not {@code null} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and * {@code ((String)env.get(prop)).equalsIgnoreCase("false")} and
* {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are * {@code ((String)env.get(prop)).equalsIgnoreCase("true")} are
* {@code false}. * {@code false}.
* @throws ClassCastException if {@code env.get(prop)} cannot be cast
* to {@code String}.
*/ */
public static boolean computeBooleanFromString( public static boolean computeBooleanFromString( String stringBoolean, boolean defaultValue) {
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));
}
if (stringBoolean == null) if (stringBoolean == null)
return defaultValue; return defaultValue;
else if (stringBoolean.equalsIgnoreCase("true")) else if (stringBoolean.equalsIgnoreCase("true"))
@ -763,8 +723,8 @@ public class EnvHelp {
else if (stringBoolean.equalsIgnoreCase("false")) else if (stringBoolean.equalsIgnoreCase("false"))
return false; return false;
else else
throw new IllegalArgumentException(prop + throw new IllegalArgumentException(
" must be \"true\" or \"false\" instead of \"" + "Property value must be \"true\" or \"false\" instead of \"" +
stringBoolean + "\""); stringBoolean + "\"");
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,9 @@ import com.sun.beans.decoder.DocumentHandler;
import java.io.Closeable; import java.io.Closeable;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; 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.InputSource;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
@ -61,6 +64,7 @@ import org.xml.sax.helpers.DefaultHandler;
* @author Philip Milne * @author Philip Milne
*/ */
public class XMLDecoder implements AutoCloseable { public class XMLDecoder implements AutoCloseable {
private final AccessControlContext acc = AccessController.getContext();
private final DocumentHandler handler = new DocumentHandler(); private final DocumentHandler handler = new DocumentHandler();
private final InputSource input; private final InputSource input;
private Object owner; private Object owner;
@ -189,7 +193,15 @@ public class XMLDecoder implements AutoCloseable {
return false; return false;
} }
if (this.array == null) { 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(); this.array = this.handler.getObjects();
} }
return true; return true;

View File

@ -407,7 +407,7 @@ public final class FilePermission extends Permission implements Serializable {
* @return a hash code value for this object. * @return a hash code value for this object.
*/ */
public int hashCode() { public int hashCode() {
return this.cpath.hashCode(); return 0;
} }
/** /**

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,13 +25,14 @@
package java.lang.invoke; package java.lang.invoke;
import sun.invoke.util.VerifyType; import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import sun.invoke.empty.Empty; import sun.invoke.empty.Empty;
import sun.invoke.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleStatics.*;
@ -781,4 +782,168 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return mh; 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);
}
}
}
} }

View File

@ -385,4 +385,101 @@ class MethodHandleNatives {
throw err; 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;
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -108,7 +108,7 @@ import sun.misc.Unsafe;
/*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) { /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
return new IllegalArgumentException(message(message, obj, 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); throw new InternalError("uncaught exception", ex);
} }
static Error NYI() { static Error NYI() {

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -329,6 +329,7 @@ public class MethodHandles {
* where {@code defcPkg} is the package of {@code defc}. * where {@code defcPkg} is the package of {@code defc}.
* </ul> * </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 public static final
class Lookup { class Lookup {
/** The class on behalf of whom the lookup is being performed. */ /** The class on behalf of whom the lookup is being performed. */
@ -1209,6 +1210,7 @@ return mh1;
if (method.isMethodHandleInvoke()) if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method); return fakeMethodHandleInvoke(method);
MethodHandle mh = DirectMethodHandle.make(refc, method); MethodHandle mh = DirectMethodHandle.make(refc, method);
mh = maybeBindCaller(method, mh);
mh = mh.setVarargs(method); mh = mh.setVarargs(method);
if (doRestrict) if (doRestrict)
mh = restrictReceiver(method, mh, lookupClass()); mh = restrictReceiver(method, mh, lookupClass());
@ -1217,6 +1219,16 @@ return mh1;
private MethodHandle fakeMethodHandleInvoke(MemberName method) { private MethodHandle fakeMethodHandleInvoke(MemberName method) {
return throwException(method.getReturnType(), UnsupportedOperationException.class); 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 { private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
checkField(refKind, refc, field); checkField(refKind, refc, field);
MethodHandle mh = DirectMethodHandle.make(refc, field); MethodHandle mh = DirectMethodHandle.make(refc, field);
@ -1229,6 +1241,7 @@ return mh1;
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException { private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
assert(ctor.isConstructor()); assert(ctor.isConstructor());
checkAccess(REF_newInvokeSpecial, refc, ctor); checkAccess(REF_newInvokeSpecial, refc, ctor);
assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
return DirectMethodHandle.make(ctor).setVarargs(ctor); return DirectMethodHandle.make(ctor).setVarargs(ctor);
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -290,11 +290,11 @@ public final class AccessController {
*/ */
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
DomainCombiner dc = null;
AccessControlContext acc = getStackAccessControlContext(); AccessControlContext acc = getStackAccessControlContext();
if (acc == null || (dc = acc.getAssignedCombiner()) == null) { if (acc == null) {
return AccessController.doPrivileged(action); return AccessController.doPrivileged(action);
} }
DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc)); return AccessController.doPrivileged(action, preserveCombiner(dc));
} }
@ -386,11 +386,11 @@ public final class AccessController {
public static <T> T doPrivilegedWithCombiner public static <T> T doPrivilegedWithCombiner
(PrivilegedExceptionAction<T> action) throws PrivilegedActionException { (PrivilegedExceptionAction<T> action) throws PrivilegedActionException {
DomainCombiner dc = null;
AccessControlContext acc = getStackAccessControlContext(); AccessControlContext acc = getStackAccessControlContext();
if (acc == null || (dc = acc.getAssignedCombiner()) == null) { if (acc == null) {
return AccessController.doPrivileged(action); return AccessController.doPrivileged(action);
} }
DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action, preserveCombiner(dc)); return AccessController.doPrivileged(action, preserveCombiner(dc));
} }
@ -417,7 +417,12 @@ public final class AccessController {
// perform 'combine' on the caller of doPrivileged, // perform 'combine' on the caller of doPrivileged,
// even if the caller is from the bootclasspath // even if the caller is from the bootclasspath
ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; 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);
}
} }

View File

@ -358,14 +358,21 @@ public final class ServiceLoader<S>
} }
String cn = nextName; String cn = nextName;
nextName = null; nextName = null;
Class<?> c = null;
try { try {
S p = service.cast(Class.forName(cn, true, loader) c = Class.forName(cn, false, loader);
.newInstance());
providers.put(cn, p);
return p;
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
fail(service, fail(service,
"Provider " + cn + " not found"); "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) { } catch (Throwable x) {
fail(service, fail(service,
"Provider " + cn + " could not be instantiated: " + x, "Provider " + cn + " could not be instantiated: " + x,

View File

@ -530,18 +530,17 @@ public class Executors {
return AccessController.doPrivileged( return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() { new PrivilegedExceptionAction<T>() {
public T run() throws Exception { public T run() throws Exception {
ClassLoader savedcl = null;
Thread t = Thread.currentThread(); Thread t = Thread.currentThread();
try { ClassLoader cl = t.getContextClassLoader();
ClassLoader cl = t.getContextClassLoader(); if (ccl == cl) {
if (ccl != cl) {
t.setContextClassLoader(ccl);
savedcl = cl;
}
return task.call(); return task.call();
} finally { } else {
if (savedcl != null) t.setContextClassLoader(ccl);
t.setContextClassLoader(savedcl); try {
return task.call();
} finally {
t.setContextClassLoader(cl);
}
} }
} }
}, acc); }, acc);

View File

@ -220,7 +220,7 @@ public class FileHandler extends StreamHandler {
* @exception NullPointerException if pattern property is an empty String. * @exception NullPointerException if pattern property is an empty String.
*/ */
public FileHandler() throws IOException, SecurityException { public FileHandler() throws IOException, SecurityException {
checkAccess(); checkPermission();
configure(); configure();
openFiles(); openFiles();
} }
@ -246,7 +246,7 @@ public class FileHandler extends StreamHandler {
if (pattern.length() < 1 ) { if (pattern.length() < 1 ) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkAccess(); checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = 0; this.limit = 0;
@ -278,7 +278,7 @@ public class FileHandler extends StreamHandler {
if (pattern.length() < 1 ) { if (pattern.length() < 1 ) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkAccess(); checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = 0; this.limit = 0;
@ -315,7 +315,7 @@ public class FileHandler extends StreamHandler {
if (limit < 0 || count < 1 || pattern.length() < 1) { if (limit < 0 || count < 1 || pattern.length() < 1) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkAccess(); checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = limit; this.limit = limit;
@ -354,7 +354,7 @@ public class FileHandler extends StreamHandler {
if (limit < 0 || count < 1 || pattern.length() < 1) { if (limit < 0 || count < 1 || pattern.length() < 1) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkAccess(); checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = limit; this.limit = limit;
@ -367,7 +367,7 @@ public class FileHandler extends StreamHandler {
// configured instance variables. // configured instance variables.
private void openFiles() throws IOException { private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager(); LogManager manager = LogManager.getLogManager();
manager.checkAccess(); manager.checkPermission();
if (count < 1) { if (count < 1) {
throw new IllegalArgumentException("file count = " + count); throw new IllegalArgumentException("file count = " + count);
} }

View File

@ -111,7 +111,7 @@ public abstract class Handler {
* the caller does not have <tt>LoggingPermission("control")</tt>. * the caller does not have <tt>LoggingPermission("control")</tt>.
*/ */
public void setFormatter(Formatter newFormatter) throws SecurityException { public void setFormatter(Formatter newFormatter) throws SecurityException {
checkAccess(); checkPermission();
// Check for a null pointer: // Check for a null pointer:
newFormatter.getClass(); newFormatter.getClass();
formatter = newFormatter; formatter = newFormatter;
@ -140,7 +140,7 @@ public abstract class Handler {
*/ */
public void setEncoding(String encoding) public void setEncoding(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException { throws SecurityException, java.io.UnsupportedEncodingException {
checkAccess(); checkPermission();
if (encoding != null) { if (encoding != null) {
try { try {
if(!java.nio.charset.Charset.isSupported(encoding)) { if(!java.nio.charset.Charset.isSupported(encoding)) {
@ -175,7 +175,7 @@ public abstract class Handler {
* the caller does not have <tt>LoggingPermission("control")</tt>. * the caller does not have <tt>LoggingPermission("control")</tt>.
*/ */
public void setFilter(Filter newFilter) throws SecurityException { public void setFilter(Filter newFilter) throws SecurityException {
checkAccess(); checkPermission();
filter = newFilter; filter = newFilter;
} }
@ -199,7 +199,7 @@ public abstract class Handler {
* the caller does not have <tt>LoggingPermission("control")</tt>. * the caller does not have <tt>LoggingPermission("control")</tt>.
*/ */
public void setErrorManager(ErrorManager em) { public void setErrorManager(ErrorManager em) {
checkAccess(); checkPermission();
if (em == null) { if (em == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -213,7 +213,7 @@ public abstract class Handler {
* the caller does not have <tt>LoggingPermission("control")</tt>. * the caller does not have <tt>LoggingPermission("control")</tt>.
*/ */
public ErrorManager getErrorManager() { public ErrorManager getErrorManager() {
checkAccess(); checkPermission();
return errorManager; return errorManager;
} }
@ -253,7 +253,7 @@ public abstract class Handler {
if (newLevel == null) { if (newLevel == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
checkAccess(); checkPermission();
logLevel = newLevel; logLevel = newLevel;
} }
@ -296,9 +296,9 @@ public abstract class Handler {
// If "sealed" is true, we check that the caller has // If "sealed" is true, we check that the caller has
// appropriate security privileges to update Handler // appropriate security privileges to update Handler
// state and if not throw a SecurityException. // state and if not throw a SecurityException.
void checkAccess() throws SecurityException { void checkPermission() throws SecurityException {
if (sealed) { if (sealed) {
manager.checkAccess(); manager.checkPermission();
} }
} }
} }

View File

@ -321,7 +321,7 @@ public class LogManager {
@Deprecated @Deprecated
public void addPropertyChangeListener(PropertyChangeListener l) throws SecurityException { public void addPropertyChangeListener(PropertyChangeListener l) throws SecurityException {
PropertyChangeListener listener = Objects.requireNonNull(l); PropertyChangeListener listener = Objects.requireNonNull(l);
checkAccess(); checkPermission();
synchronized (listenerMap) { synchronized (listenerMap) {
// increment the registration count if already registered // increment the registration count if already registered
Integer value = listenerMap.get(listener); Integer value = listenerMap.get(listener);
@ -352,7 +352,7 @@ public class LogManager {
*/ */
@Deprecated @Deprecated
public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException { public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException {
checkAccess(); checkPermission();
if (l != null) { if (l != null) {
PropertyChangeListener listener = l; PropertyChangeListener listener = l;
synchronized (listenerMap) { synchronized (listenerMap) {
@ -807,7 +807,7 @@ public class LogManager {
* @exception IOException if there are IO problems reading the configuration. * @exception IOException if there are IO problems reading the configuration.
*/ */
public void readConfiguration() throws IOException, SecurityException { public void readConfiguration() throws IOException, SecurityException {
checkAccess(); checkPermission();
// if a configuration class is specified, load it and use it. // if a configuration class is specified, load it and use it.
String cname = System.getProperty("java.util.logging.config.class"); String cname = System.getProperty("java.util.logging.config.class");
@ -865,7 +865,7 @@ public class LogManager {
*/ */
public void reset() throws SecurityException { public void reset() throws SecurityException {
checkAccess(); checkPermission();
synchronized (this) { synchronized (this) {
props = new Properties(); props = new Properties();
// Since we are doing a reset we no longer want to initialize // Since we are doing a reset we no longer want to initialize
@ -950,7 +950,7 @@ public class LogManager {
* @exception IOException if there are problems reading from the stream. * @exception IOException if there are problems reading from the stream.
*/ */
public void readConfiguration(InputStream ins) throws IOException, SecurityException { public void readConfiguration(InputStream ins) throws IOException, SecurityException {
checkAccess(); checkPermission();
reset(); reset();
// Load the properties // Load the properties
@ -1127,8 +1127,13 @@ public class LogManager {
loadLoggerHandlers(rootLogger, null, "handlers"); 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 * Check that the current context is trusted to modify the logging
@ -1141,11 +1146,7 @@ public class LogManager {
* the caller does not have LoggingPermission("control"). * the caller does not have LoggingPermission("control").
*/ */
public void checkAccess() throws SecurityException { public void checkAccess() throws SecurityException {
SecurityManager sm = System.getSecurityManager(); checkPermission();
if (sm == null) {
return;
}
sm.checkPermission(ourPermission);
} }
// Nested class to represent a node in our tree of named loggers. // Nested class to represent a node in our tree of named loggers.

View File

@ -276,13 +276,13 @@ public class Logger {
this.manager = manager; this.manager = manager;
} }
private void checkAccess() throws SecurityException { private void checkPermission() throws SecurityException {
if (!anonymous) { if (!anonymous) {
if (manager == null) { if (manager == null) {
// Complete initialization of the global Logger. // Complete initialization of the global Logger.
manager = LogManager.getLogManager(); manager = LogManager.getLogManager();
} }
manager.checkAccess(); manager.checkPermission();
} }
} }
@ -482,7 +482,7 @@ public class Logger {
* the caller does not have LoggingPermission("control"). * the caller does not have LoggingPermission("control").
*/ */
public void setFilter(Filter newFilter) throws SecurityException { public void setFilter(Filter newFilter) throws SecurityException {
checkAccess(); checkPermission();
filter = newFilter; filter = newFilter;
} }
@ -1168,7 +1168,7 @@ public class Logger {
* the caller does not have LoggingPermission("control"). * the caller does not have LoggingPermission("control").
*/ */
public void setLevel(Level newLevel) throws SecurityException { public void setLevel(Level newLevel) throws SecurityException {
checkAccess(); checkPermission();
synchronized (treeLock) { synchronized (treeLock) {
levelObject = newLevel; levelObject = newLevel;
updateEffectiveLevel(); updateEffectiveLevel();
@ -1223,7 +1223,7 @@ public class Logger {
public void addHandler(Handler handler) throws SecurityException { public void addHandler(Handler handler) throws SecurityException {
// Check for null handler // Check for null handler
handler.getClass(); handler.getClass();
checkAccess(); checkPermission();
handlers.add(handler); handlers.add(handler);
} }
@ -1237,7 +1237,7 @@ public class Logger {
* the caller does not have LoggingPermission("control"). * the caller does not have LoggingPermission("control").
*/ */
public void removeHandler(Handler handler) throws SecurityException { public void removeHandler(Handler handler) throws SecurityException {
checkAccess(); checkPermission();
if (handler == null) { if (handler == null) {
return; return;
} }
@ -1265,7 +1265,7 @@ public class Logger {
* the caller does not have LoggingPermission("control"). * the caller does not have LoggingPermission("control").
*/ */
public void setUseParentHandlers(boolean useParentHandlers) { public void setUseParentHandlers(boolean useParentHandlers) {
checkAccess(); checkPermission();
this.useParentHandlers = useParentHandlers; this.useParentHandlers = useParentHandlers;
} }
@ -1420,7 +1420,7 @@ public class Logger {
if (parent == null) { if (parent == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
manager.checkAccess(); manager.checkPermission();
doSetParent(parent); doSetParent(parent);
} }

View File

@ -238,7 +238,7 @@ public class MemoryHandler extends Handler {
throw new NullPointerException(); throw new NullPointerException();
} }
LogManager manager = LogManager.getLogManager(); LogManager manager = LogManager.getLogManager();
checkAccess(); checkPermission();
pushLevel = newLevel; pushLevel = newLevel;
} }

View File

@ -249,7 +249,7 @@ public class StreamHandler extends Handler {
} }
private synchronized void flushAndClose() throws SecurityException { private synchronized void flushAndClose() throws SecurityException {
checkAccess(); checkPermission();
if (writer != null) { if (writer != null) {
try { try {
if (!doneHeader) { if (!doneHeader) {

View File

@ -1245,13 +1245,12 @@ public class DescriptorSupport
return s.substring(1, s.length() - 1); return s.substring(1, s.length() - 1);
} }
final String className = s.substring(1, slash); final String className = s.substring(1, slash);
final Constructor<?> constr; final Constructor<?> constr;
try { try {
ReflectUtil.checkPackageAccess(className);
final ClassLoader contextClassLoader = final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader(); Thread.currentThread().getContextClassLoader();
if (contextClassLoader == null) {
ReflectUtil.checkPackageAccess(className);
}
final Class<?> c = final Class<?> c =
Class.forName(className, false, contextClassLoader); Class.forName(className, false, contextClassLoader);
constr = c.getConstructor(new Class<?>[] {String.class}); constr = c.getConstructor(new Class<?>[] {String.class});

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,30 @@
package javax.management.remote.rmi; 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 static com.sun.jmx.mbeanserver.Util.cast;
import com.sun.jmx.remote.internal.ServerCommunicatorAdmin; import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
import com.sun.jmx.remote.internal.ServerNotifForwarder; import com.sun.jmx.remote.internal.ServerNotifForwarder;
@ -35,44 +59,6 @@ import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp; import com.sun.jmx.remote.util.EnvHelp;
import com.sun.jmx.remote.util.OrderClassLoaders; 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 * <p>Implementation of the {@link RMIConnection} interface. User
* code will not usually reference this class.</p> * code will not usually reference this class.</p>
@ -143,6 +129,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
this.mbeanServer = rmiServer.getMBeanServer(); this.mbeanServer = rmiServer.getMBeanServer();
final ClassLoader dcl = defaultClassLoader; final ClassLoader dcl = defaultClassLoader;
this.classLoaderWithRepository = this.classLoaderWithRepository =
AccessController.doPrivileged( AccessController.doPrivileged(
new PrivilegedAction<ClassLoaderWithRepository>() { new PrivilegedAction<ClassLoaderWithRepository>() {
@ -151,13 +138,40 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
mbeanServer.getClassLoaderRepository(), mbeanServer.getClassLoaderRepository(),
dcl); 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 serverCommunicatorAdmin = new
RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
this.env = 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() { private synchronized ServerNotifForwarder getServerNotifFwd() {
// Lazily created when first use. Mainly when // Lazily created when first use. Mainly when
// addNotificationListener is first called. // addNotificationListener is first called.
@ -507,7 +521,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
"connectionId=" + connectionId "connectionId=" + connectionId
+" unwrapping query with defaultClassLoader."); +" unwrapping query with defaultClassLoader.");
queryValue = unwrap(query, defaultClassLoader, QueryExp.class); queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class);
try { try {
final Object params[] = new Object[] { name, queryValue }; final Object params[] = new Object[] { name, queryValue };
@ -542,7 +556,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
"connectionId=" + connectionId "connectionId=" + connectionId
+" unwrapping query with defaultClassLoader."); +" unwrapping query with defaultClassLoader.");
queryValue = unwrap(query, defaultClassLoader, QueryExp.class); queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class);
try { try {
final Object params[] = new Object[] { name, queryValue }; final Object params[] = new Object[] { name, queryValue };
@ -1330,7 +1344,9 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
public ClassLoader run() throws InstanceNotFoundException { public ClassLoader run() throws InstanceNotFoundException {
return mbeanServer.getClassLoader(name); return mbeanServer.getClassLoader(name);
} }
}); },
withPermissions(new MBeanPermission("*", "getClassLoader"))
);
} catch (PrivilegedActionException pe) { } catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe); throw (InstanceNotFoundException) extractException(pe);
} }
@ -1345,7 +1361,9 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
public Object run() throws InstanceNotFoundException { public Object run() throws InstanceNotFoundException {
return mbeanServer.getClassLoaderFor(name); return mbeanServer.getClassLoaderFor(name);
} }
}); },
withPermissions(new MBeanPermission("*", "getClassLoaderFor"))
);
} catch (PrivilegedActionException pe) { } catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe); throw (InstanceNotFoundException) extractException(pe);
} }
@ -1572,7 +1590,8 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
ClassLoader orderCL = AccessController.doPrivileged( ClassLoader orderCL = AccessController.doPrivileged(
new PrivilegedExceptionAction<ClassLoader>() { new PrivilegedExceptionAction<ClassLoader>() {
public ClassLoader run() throws Exception { public ClassLoader run() throws Exception {
return new OrderClassLoaders(cl1, cl2); return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
new OrderClassLoaders(cl1, cl2));
} }
} }
); );
@ -1664,6 +1683,8 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
private final ClassLoader defaultClassLoader; private final ClassLoader defaultClassLoader;
private final ClassLoader defaultContextClassLoader;
private final ClassLoaderWithRepository classLoaderWithRepository; private final ClassLoaderWithRepository classLoaderWithRepository;
private boolean terminated = false; private boolean terminated = false;
@ -1746,4 +1767,43 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
private static final ClassLogger logger = private static final ClassLogger logger =
new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl"); 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;
}
}
} }

View File

@ -277,9 +277,9 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
// Check for secure RMIServer stub if the corresponding // Check for secure RMIServer stub if the corresponding
// client-side environment property is set to "true". // client-side environment property is set to "true".
// //
boolean checkStub = EnvHelp.computeBooleanFromString( String stringBoolean = (String) usemap.get("jmx.remote.x.check.stub");
usemap, boolean checkStub = EnvHelp.computeBooleanFromString(stringBoolean);
"jmx.remote.x.check.stub",false);
if (checkStub) checkStub(stub, rmiServerImplStubClass); if (checkStub) checkStub(stub, rmiServerImplStubClass);
// Connect IIOP Stub if needed. // Connect IIOP Stub if needed.

View File

@ -412,9 +412,8 @@ public class RMIConnectorServer extends JMXConnectorServer {
if (tracing) if (tracing)
logger.trace("start", "Using external directory: " + jndiUrl); logger.trace("start", "Using external directory: " + jndiUrl);
final boolean rebind = EnvHelp.computeBooleanFromString( String stringBoolean = (String) attributes.get(JNDI_REBIND_ATTRIBUTE);
attributes, final boolean rebind = EnvHelp.computeBooleanFromString( stringBoolean );
JNDI_REBIND_ATTRIBUTE,false);
if (tracing) if (tracing)
logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind); logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);

View File

@ -24,6 +24,8 @@
*/ */
package javax.swing.text; package javax.swing.text;
import sun.reflect.misc.ConstructorUtil;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.text.ParseException; import java.text.ParseException;
@ -245,7 +247,7 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter
Constructor cons; Constructor cons;
try { try {
cons = vc.getConstructor(new Class[] { String.class }); cons = ConstructorUtil.getConstructor(vc, new Class[]{String.class});
} catch (NoSuchMethodException nsme) { } catch (NoSuchMethodException nsme) {
cons = null; cons = null;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -73,74 +73,14 @@ import sun.misc.IOUtils;
public class AnonymousClassLoader { public class AnonymousClassLoader {
final Class<?> hostClass; final Class<?> hostClass;
// Note: Do not refactor the calls to checkHostClass unless you // Privileged constructor.
// also adjust this constant: private AnonymousClassLoader(Class<?> hostClass) {
private static int CHC_CALLERS = 3; this.hostClass = hostClass;
public AnonymousClassLoader() {
this.hostClass = checkHostClass(null);
}
public AnonymousClassLoader(Class<?> hostClass) {
this.hostClass = checkHostClass(hostClass);
} }
private static Class<?> getTopLevelClass(Class<?> clazz) { public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class<?> hostClass) {
for(Class<?> outer = clazz.getDeclaringClass(); outer != null; if (unsafe == null) throw new NullPointerException();
outer = outer.getDeclaringClass()) { return new AnonymousClassLoader(hostClass);
clazz = outer;
}
return clazz;
}
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 Class<?> loadClass(byte[] classFile) { public Class<?> loadClass(byte[] classFile) {
@ -249,7 +189,7 @@ public class AnonymousClassLoader {
private static int fakeNameCounter = 99999; private static int fakeNameCounter = 99999;
// ignore two warnings on this line: // 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 // preceding line requires that this class be on the boot class path
static private final Method defineAnonymousClass; static private final Method defineAnonymousClass;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -522,13 +522,19 @@ public class ValueConversions {
static { static {
MethodHandle mh = null; MethodHandle mh = null;
try { try {
java.lang.reflect.Method m = MethodHandles.class final java.lang.reflect.Method m = MethodHandles.class
.getDeclaredMethod("collectArguments", .getDeclaredMethod("collectArguments",
MethodHandle.class, int.class, MethodHandle.class); 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); mh = IMPL_LOOKUP.unreflect(m);
} catch (ReflectiveOperationException | SecurityException ex) { } catch (ReflectiveOperationException ex) {
throw new InternalError(ex); throw new InternalError(ex);
} }
COLLECT_ARGUMENTS = mh; COLLECT_ARGUMENTS = mh;

View File

@ -284,12 +284,20 @@ public final class Service<S> {
} }
String cn = nextName; String cn = nextName;
nextName = null; nextName = null;
Class<?> c = null;
try { try {
return service.cast(Class.forName(cn, true, loader).newInstance()); c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
fail(service, fail(service,
"Provider " + cn + " not found"); "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, fail(service,
"Provider " + cn + " could not be instantiated: " + x, "Provider " + cn + " could not be instantiated: " + x,
x); x);

View File

@ -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) {
}
}
}

View File

@ -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;
}
}

View File

@ -405,7 +405,8 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
*/ */
perms.add(new SocketPermission("*", "connect,accept")); 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")); perms.add(new FilePermission("<<ALL FILES>>", "read"));

View File

@ -56,12 +56,6 @@ implements java.io.Serializable {
private static final long serialVersionUID = 3581829991155417889L; 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 static final int DIGEST_SIZE = 20;
private transient MessageDigest digest; private transient MessageDigest digest;
private byte[] state; private byte[] state;
@ -172,6 +166,28 @@ implements java.io.Serializable {
state[0]++; state[0]++;
} }
/**
* 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. * Generates a user-specified number of random bytes.
* *
@ -183,13 +199,8 @@ implements java.io.Serializable {
byte[] output = remainder; byte[] output = remainder;
if (state == null) { if (state == null) {
if (seeder == null) {
seeder = new SecureRandom(SeedGenerator.getSystemEntropy());
seeder.engineSetSeed(engineGenerateSeed(DIGEST_SIZE));
}
byte[] seed = new byte[DIGEST_SIZE]; byte[] seed = new byte[DIGEST_SIZE];
seeder.engineNextBytes(seed); SeederHolder.seeder.engineNextBytes(seed);
state = digest.digest(seed); state = digest.digest(seed);
} }

View File

@ -191,6 +191,7 @@ public class HandshakeInStream extends InputStream {
byte[] getBytes8() throws IOException { byte[] getBytes8() throws IOException {
int len = getInt8(); int len = getInt8();
verifyLength(len);
byte b[] = new byte[len]; byte b[] = new byte[len];
read(b, 0, len); read(b, 0, len);
@ -199,6 +200,7 @@ public class HandshakeInStream extends InputStream {
public byte[] getBytes16() throws IOException { public byte[] getBytes16() throws IOException {
int len = getInt16(); int len = getInt16();
verifyLength(len);
byte b[] = new byte[len]; byte b[] = new byte[len];
read(b, 0, len); read(b, 0, len);
@ -207,10 +209,19 @@ public class HandshakeInStream extends InputStream {
byte[] getBytes24() throws IOException { byte[] getBytes24() throws IOException {
int len = getInt24(); int len = getInt24();
verifyLength(len);
byte b[] = new byte[len]; byte b[] = new byte[len];
read(b, 0, len); read(b, 0, len);
return b; 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");
}
}
} }

View File

@ -1079,7 +1079,6 @@ abstract class Handshaker {
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:"); System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out); e.printStackTrace(System.out);
System.out.println("Generating new random premaster secret");
} }
if (requestedVersion != null) { if (requestedVersion != null) {
@ -1146,7 +1145,6 @@ abstract class Handshaker {
System.out.println("RSA PreMasterSecret version error: expected" System.out.println("RSA PreMasterSecret version error: expected"
+ protocolVersion + " or " + requestedVersion + ", decrypted: " + protocolVersion + " or " + requestedVersion + ", decrypted: "
+ premasterVersion); + premasterVersion);
System.out.println("Generating new random premaster secret");
} }
preMasterSecret = preMasterSecret =
RSAClientKeyExchange.generateDummySecret(requestedVersion); RSAClientKeyExchange.generateDummySecret(requestedVersion);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@ import javax.crypto.spec.*;
import javax.net.ssl.*; import javax.net.ssl.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
import sun.security.util.KeyLength;
/** /**
* This is the client key exchange message (CLIENT --> SERVER) used with * This is the client key exchange message (CLIENT --> SERVER) used with
@ -192,26 +193,38 @@ final class RSAClientKeyExchange extends HandshakeMessage {
"unable to get the plaintext of the premaster secret"); "unable to get the plaintext of the premaster secret");
} }
// We are not always able to get the encoded key of the int keySize = KeyLength.getKeySize(secretKey);
// premaster secret. Pass the cheking to master secret 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. // calculation.
return secretKey; return secretKey;
} else if (encoded.length == 48) { } else if (encoded.length == 48) {
// check the version // check the version
if (clientHelloVersion.major == encoded[0] && if (clientHelloVersion.major == encoded[0] &&
clientHelloVersion.minor == encoded[1]) { clientHelloVersion.minor == encoded[1]) {
return secretKey; 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 compatibility, we maintain the behavior that the
* for TLS v1.0 and SSL v3.0. For compatibility, we * version in pre_master_secret can be the negotiated
* maintain this behavior. * version for TLS v1.0 and SSL v3.0.
*/ */
if (currentVersion.major == encoded[0] && this.protocolVersion = currentVersion;
currentVersion.minor == encoded[1]) { return secretKey;
this.protocolVersion = currentVersion;
return secretKey;
}
} }
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
@ -220,22 +233,23 @@ final class RSAClientKeyExchange extends HandshakeMessage {
", while PreMasterSecret.client_version is " + ", while PreMasterSecret.client_version is " +
ProtocolVersion.valueOf(encoded[0], encoded[1])); ProtocolVersion.valueOf(encoded[0], encoded[1]));
} }
return generateDummySecret(clientHelloVersion);
} else { } else {
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
System.out.println( System.out.println(
"incorrect length of premaster secret: " + "incorrect length of premaster secret: " +
encoded.length); encoded.length);
} }
return generateDummySecret(clientHelloVersion);
} }
} }
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake") &&
if (failoverException != null) { failoverException != null) {
System.out.println("Error decrypting premaster secret:"); System.out.println("Error decrypting premaster secret:");
failoverException.printStackTrace(System.out); failoverException.printStackTrace(System.out);
}
System.out.println("Generating random secret");
} }
return generateDummySecret(clientHelloVersion); return generateDummySecret(clientHelloVersion);
@ -243,6 +257,10 @@ final class RSAClientKeyExchange extends HandshakeMessage {
// generate a premaster secret with the specified version number // generate a premaster secret with the specified version number
static SecretKey generateDummySecret(ProtocolVersion version) { static SecretKey generateDummySecret(ProtocolVersion version) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Generating a random fake premaster secret");
}
try { try {
String s = ((version.v >= ProtocolVersion.TLS12.v) ? String s = ((version.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret"); "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");

View File

@ -145,7 +145,7 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # List of comma-separated packages that start with or equal this string
@ -157,7 +157,7 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -146,7 +146,7 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # List of comma-separated packages that start with or equal this string
@ -158,7 +158,7 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -147,7 +147,7 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # List of comma-separated packages that start with or equal this string
@ -159,7 +159,7 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -146,7 +146,7 @@ keystore.type=jks
# passed to checkPackageAccess unless the # passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has # corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted. # 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 # List of comma-separated packages that start with or equal this string
@ -158,7 +158,7 @@ package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.
# by default, none of the class loaders supplied with the JDK call # by default, none of the class loaders supplied with the JDK call
# checkPackageDefinition. # 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 # Determines whether this properties file can be appended to

View File

@ -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");
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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";
};

View File

@ -322,10 +322,6 @@ public class Test {
test("ftp://ftp.is.co.za/rfc/rfc1808.txt") test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
.s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); .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") 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(); .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z();