--- a/jdk/src/share/classes/java/lang/Class.java Wed Apr 17 10:15:33 2013 +0800
+++ b/jdk/src/share/classes/java/lang/Class.java Tue Apr 16 21:39:52 2013 -0700
@@ -53,6 +53,7 @@
import java.util.HashMap;
import java.util.Objects;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
@@ -250,9 +251,11 @@
* by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
+ @CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
- return forName0(className, true, ClassLoader.getCallerClassLoader());
+ return forName0(className, true,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
@@ -317,6 +320,7 @@
* @see java.lang.ClassLoader
* @since 1.2
*/
+ @CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
@@ -324,7 +328,7 @@
if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
+ ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
@@ -386,18 +390,14 @@
* </ul>
*
*/
+ @CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
- return newInstance0();
- }
- private T newInstance0()
- throws InstantiationException, IllegalAccessException
- {
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
@@ -432,7 +432,7 @@
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(3);
+ Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
@@ -674,16 +674,14 @@
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
+ @CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ClassLoader.needsClassLoaderPermissionCheck(ccl, cl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
@@ -1392,11 +1390,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Class<?>[] getClasses() {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1467,11 +1463,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field[] getFields() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1518,11 +1512,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method[] getMethods() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1567,11 +1559,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1625,12 +1615,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1710,12 +1698,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1764,12 +1750,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1807,11 +1791,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
return getDeclaredClasses0();
}
@@ -1851,11 +1833,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1899,11 +1879,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1944,11 +1922,9 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -1987,12 +1963,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -2042,12 +2016,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2092,12 +2064,10 @@
*
* @since JDK1.1
*/
+ @CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
- // be very careful not to change the stack depth of this
- // checkMemberAccess call for security reasons
- // see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2255,23 +2225,40 @@
*/
static native Class<?> getPrimitiveClass(String name);
+ private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
+ if (smgr.getClass() == SecurityManager.class) return false;
+
+ Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
+ return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
+ getDeclaringClass() != SecurityManager.class;
+ }
/*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
- * Be very careful not to change the stack depth of this checkMemberAccess
- * call for security reasons.
- * See java.lang.SecurityManager.checkMemberAccess.
- *
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
- SecurityManager s = System.getSecurityManager();
+ private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
if (s != null) {
- s.checkMemberAccess(this, which);
- ClassLoader cl = getClassLoader0();
+ final ClassLoader ccl = ClassLoader.getClassLoader(caller);
+ final ClassLoader cl = getClassLoader0();
+ if (!isCheckMemberAccessOverridden(s)) {
+ // Inlined SecurityManager.checkMemberAccess
+ if (which != Member.PUBLIC) {
+ if (ccl != cl) {
+ s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
+ }
+ }
+ } else {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ s.checkMemberAccess(this, which);
+ }
+
+
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');