From cdf8c27ddb03484725a28ecc04b87510822d98e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Wed, 25 Feb 2015 14:30:02 +0100 Subject: [PATCH] 8014678: Spurious AccessControlException thrown in java.lang.Class.getEnclosingMethod() Reviewed-by: ahgross, mchung, psandoz --- .../share/classes/java/lang/Class.java | 24 +++++++-- ...closingConstructorWithSecurityManager.java | 50 +++++++++++++++++++ .../EnclosingMethodWithSecurityManager.java | 50 +++++++++++++++++++ 3 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java create mode 100644 jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 3a0c3fdf3e6..258ec369ce5 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -1063,16 +1063,24 @@ public final class Class 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() { + @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 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[]>() { + @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; diff --git a/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java b/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java new file mode 100644 index 00000000000..1c81b09fa5a --- /dev/null +++ b/jdk/test/java/lang/Class/getEnclosingConstructor/EnclosingConstructorWithSecurityManager.java @@ -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(); + } + } +} diff --git a/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java b/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java new file mode 100644 index 00000000000..fa14214cda6 --- /dev/null +++ b/jdk/test/java/lang/Class/getEnclosingMethod/EnclosingMethodWithSecurityManager.java @@ -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(); + } + } +}