Mercurial > hg > release > icedtea7-forest-2.1 > jdk
changeset 4903:0a66867d6baa
8007812: (reflect) Class.getEnclosingMethod problematic for some classes
Summary: Better checking in getEnclosing(Method|Constructor|Class)
Reviewed-by: darcy, ahgross, mchung
author | jfranck |
---|---|
date | Mon, 25 Mar 2013 20:18:21 +0100 |
parents | d22aa05d0e4c |
children | 38c68381e29f |
files | src/share/classes/java/lang/Class.java src/share/classes/java/lang/invoke/MethodHandleNatives.java |
diffstat | 2 files changed, 35 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/lang/Class.java Thu Mar 21 22:32:42 2013 +0400 +++ b/src/share/classes/java/lang/Class.java Mon Mar 25 20:18:21 2013 +0100 @@ -915,13 +915,22 @@ for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + ClassLoader.getCallerClassLoader(), true); /* * Loop over all declared methods; match method name, * number of and type of parameters, *and* return * type. Matching return type is also necessary * because of covariant returns, etc. */ - for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) { + for(Method m: enclosingCandidate.getDeclaredMethods()) { if (m.getName().equals(enclosingInfo.getName()) ) { Class<?>[] candidateParamClasses = m.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { @@ -1042,11 +1051,20 @@ for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + ClassLoader.getCallerClassLoader(), true); /* * Loop over all declared constructors; match number * of and type of parameters. */ - for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) { + for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) { Class<?>[] candidateParamClasses = c.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; @@ -1101,18 +1119,28 @@ // attribute if and only if it is a local class or an // anonymous class. EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); + Class<?> enclosingCandidate; if (enclosingInfo == null) { // This is a top level or a nested class or an inner class (a, b, or c) - return getDeclaringClass(); + enclosingCandidate = getDeclaringClass(); } else { Class<?> enclosingClass = enclosingInfo.getEnclosingClass(); // This is a local class or an anonymous class (d or e) if (enclosingClass == this || enclosingClass == null) throw new InternalError("Malformed enclosing method information"); else - return enclosingClass; + enclosingCandidate = enclosingClass; } + + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + if (enclosingCandidate != null) { + enclosingCandidate.checkMemberAccess(Member.DECLARED, + ClassLoader.getCallerClassLoader(), true); + } + return enclosingCandidate; } /**
--- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Mar 21 22:32:42 2013 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java Mon Mar 25 20:18:21 2013 +0100 @@ -480,6 +480,9 @@ case "getDeclaredField": case "getDeclaredMethod": case "getDeclaredConstructor": + case "getEnclosingClass": + case "getEnclosingMethod": + case "getEnclosingConstructor": return defc == java.lang.Class.class; case "getConnection": case "getDriver":