# HG changeset patch
# User mchung
# Date 1372796615 25200
# Node ID 64c0a3fb78cdf25cd5f8515446b058aac9b5cb7b
# Parent 6ae667b931d5389914a96c94117362eb87f92431
8014925: Disable sun.reflect.Reflection.getCallerClass(int) with a temporary switch to re-enable it
Reviewed-by: jrose, alanb, chegar, twisti
diff -r 6ae667b931d5 -r 64c0a3fb78cd src/share/classes/sun/misc/VM.java
--- openjdk/jdk/src/share/classes/sun/misc/VM.java Tue Jun 25 16:12:47 2013 -0700
+++ openjdk/jdk/src/share/classes/sun/misc/VM.java Tue Jul 02 13:23:35 2013 -0700
@@ -216,6 +216,16 @@
return allowArraySyntax;
}
+ private static boolean allowGetCallerClass = false;
+
+ // Reflection.getCallerClass(int) is disabled by default.
+ // It can be enabled by setting the system property
+ // "jdk.reflect.allowGetCallerClass" and also used by
+ // logging stack walk of a resource bundle if it is turned on.
+ public static boolean allowGetCallerClass() {
+ return allowGetCallerClass;
+ }
+
/**
* Returns the system property of the specified key saved at
* system initialization time. This method should only be used
@@ -280,6 +290,16 @@
? defaultAllowArraySyntax
: Boolean.parseBoolean(s));
+ // Reflection.getCallerClass(int) is disabled by default.
+ // It can be enabled by setting the system property
+ // "jdk.reflect.allowGetCallerClass" and also used by
+ // logging stack walk of a resource bundle if it is turned on.
+ s = props.getProperty("jdk.reflect.allowGetCallerClass");
+ allowGetCallerClass = (s != null
+ ? (s.isEmpty() || Boolean.parseBoolean(s))
+ : false) ||
+ Boolean.valueOf(props.getProperty("jdk.logging.allowStackWalkSearch"));
+
// Remove other private system properties
// used by java.lang.Integer.IntegerCache
props.remove("java.lang.Integer.IntegerCache.high");
diff -r 6ae667b931d5 -r 64c0a3fb78cd src/share/classes/sun/reflect/Reflection.java
--- openjdk/jdk/src/share/classes/sun/reflect/Reflection.java Tue Jun 25 16:12:47 2013 -0700
+++ openjdk/jdk/src/share/classes/sun/reflect/Reflection.java Tue Jul 02 13:23:35 2013 -0700
@@ -65,7 +65,15 @@
@Deprecated
@CallerSensitive
public static Class getCallerClass(int depth) {
- return getCallerClass0(depth+1);
+ if (sun.misc.VM.allowGetCallerClass()) {
+ return getCallerClass0(depth+1);
+ }
+ throw new UnsupportedOperationException("This method is in the sun.* " +
+ "namespace so it is not a supported, public interface. " +
+ "The 7u40 release notes describe a temporary mechanism " +
+ "to reenable the historical functionality of this method. " +
+ "Update code to function properly and this method will be " +
+ "removed without further warning in a subsequent 7 update release.");
}
// If the VM enforces getting caller class with @CallerSensitive,
diff -r 6ae667b931d5 -r 64c0a3fb78cd test/sun/reflect/GetCallerClass.java
--- openjdk/jdk/test/sun/reflect/GetCallerClass.java Tue Jun 25 16:12:47 2013 -0700
+++ openjdk/jdk/test/sun/reflect/GetCallerClass.java Tue Jul 02 13:23:35 2013 -0700
@@ -23,29 +23,83 @@
/*
* @test
- * @bug 8016814
- * @summary Test sun.reflect.Reflection.getCallerClass(int)
+ * @bug 8016814 8014925
+ * @summary Test sun.reflect.Reflection.getCallerClass(int) disabled by default
* @compile -XDignore.symbol.file GetCallerClass.java
- * @run main GetCallerClass
+ * @run main/othervm GetCallerClass
+ * @run main/othervm -Djdk.reflect.allowGetCallerClass GetCallerClass
+ * @run main/othervm -Djdk.reflect.allowGetCallerClass=true GetCallerClass
+ * @run main/othervm -Djdk.reflect.allowGetCallerClass=false GetCallerClass
*/
public class GetCallerClass {
public static void main(String[] args) throws Exception {
- Class<?> c = Temp.test();
- if (c != GetCallerClass.class) {
- throw new RuntimeException("Incorrect caller: " + c);
+ String s = System.getProperty("jdk.reflect.allowGetCallerClass");
+ boolean allowed;
+ if (s == null || s.equals("false")) {
+ allowed = false;
+ } else if (s.equals("") || s.equals("true")) {
+ allowed = true;
+ } else {
+ throw new RuntimeException("Unsupported test setting");
+ }
+
+ try {
+ Class<?> c = Test.test();
+ if (!allowed) {
+ throw new RuntimeException("Reflection.getCallerClass should not be allowed");
+ }
+ Class<?> caller = Test.caller();
+ if (c != GetCallerClass.class || caller != c) {
+ throw new RuntimeException("Incorrect caller: " + c);
+ }
+ Test.selfTest();
+ } catch (UnsupportedOperationException e) {
+ if (allowed) throw e;
}
}
@sun.reflect.CallerSensitive
public Class<?> getCallerClass() {
- // 0: Reflection 1: getCallerClass 2: Temp.test 3: main
+ // 0: Reflection 1: getCallerClass 2: Test.test 3: main
return sun.reflect.Reflection.getCallerClass(3);
}
- static class Temp {
+ static class Test {
+ // Returns the caller of this method
public static Class<?> test() {
return new GetCallerClass().getCallerClass();
}
+ @sun.reflect.CallerSensitive
+ public static Class<?> caller() {
+ return sun.reflect.Reflection.getCallerClass();
+ }
+ @sun.reflect.CallerSensitive
+ public static void selfTest() {
+ // 0: Reflection 1: Test.selfTest
+ Class<?> c = sun.reflect.Reflection.getCallerClass(1);
+ if (c != Test.class || caller() != c) {
+ throw new RuntimeException("Incorrect caller: " + c);
+ }
+ Inner1.deep();
+ }
+
+ static class Inner1 {
+ static void deep() {
+ deeper();
+ }
+ static void deeper() {
+ Inner2.deepest();
+ }
+ static class Inner2 {
+ static void deepest() {
+ // 0: Reflection 1: deepest 2: deeper 3: deep 4: Test.selfTest
+ Class<?> c = sun.reflect.Reflection.getCallerClass(4);
+ if (c != Test.class) {
+ throw new RuntimeException("Incorrect caller: " + c);
+ }
+ }
+ }
+ }
}
}