8014678: Spurious AccessControlException thrown in java.lang.Class.getEnclosingMethod()

Reviewed-by: ahgross, mchung, psandoz
This commit is contained in:
Joel Borggrén-Franck 2015-02-25 14:30:02 +01:00
parent 6d78b91ac9
commit cdf8c27ddb
3 changed files with 120 additions and 4 deletions

View File

@ -1063,16 +1063,24 @@ public final class Class<T> implements java.io.Serializable,
parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
// Client is ok to access declared methods but j.l.Class might not be.
Method[] candidates = AccessController.doPrivileged(
new PrivilegedAction<Method[]>() {
@Override
public Method[] run() {
return enclosingCandidate.getDeclaredMethods();
}
});
/*
* 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: enclosingCandidate.getDeclaredMethods()) {
for(Method m: candidates) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
@ -1215,14 +1223,22 @@ public final class Class<T> implements java.io.Serializable,
parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
// Client is ok to access declared methods but j.l.Class might not be.
Constructor<?>[] candidates = AccessController.doPrivileged(
new PrivilegedAction<Constructor<?>[]>() {
@Override
public Constructor<?>[] run() {
return enclosingCandidate.getDeclaredConstructors();
}
});
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
for(Constructor<?> c: candidates) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, 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 8014678
* @run main EnclosingConstructorWithSecurityManager
* @run main/othervm EnclosingConstructorWithSecurityManager "WithSecurityManager"
*/
public class EnclosingConstructorWithSecurityManager {
public static void main(String[] args) {
if (args.length == 1) {
System.setSecurityManager(new SecurityManager());
}
new Inner();
Inner.theInner.getEnclosingConstructor();
}
public static class Inner {
public static Class<?> theInner;
public Inner() {
Object o = new Object() {
};
Inner.theInner = o.getClass();
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, 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 8014678
* @run main EnclosingMethodWithSecurityManager
* @run main/othervm EnclosingMethodWithSecurityManager "WithSecurityManager"
*/
public class EnclosingMethodWithSecurityManager {
public static void main(String[] args) {
if (args.length == 1) {
System.setSecurityManager(new SecurityManager());
}
new Inner().setTheInner();
Inner.theInner.getEnclosingMethod();
}
public static class Inner {
public static Class<?> theInner;
public void setTheInner() {
Object o = new Object() {
};
Inner.theInner = o.getClass();
}
}
}