Duplicate :
|
|
Duplicate :
|
|
Relates :
|
|
Relates :
|
Name: boT120536 Date: 01/23/2001 java version "1.3.0" Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C) Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode) The reflection API is unclear as to whether synthetic members (classes, constructors, methods, and fields) are to show up during reflection. In my opinion, they should not be visible to reflection, as synthetic members are only meant to be accessed by trusted code generated by the compiler, not haphazardly by reflection. This is particularly true since other compilers do not have to follow the same naming convention as JDK; so simply compiling identical source on different compilers can lead to different program results, although Java source code is supposed to behave identically regardless of the compiler. However, if you do decide that synthetic members should be accessible, you should probably have a separate API to get to them (such as Class.getSyntheticMethod()), and you should include Modifier.SYNTHETIC as a way to identify such members. You may also consider adding appropriate Securities to the reflection of synthetic members, because there could be a security breach if a user can access the private members of a class by figuring out the right synthetic methods to reflect. It appears that JDK creates all its synthetic members with at most default (package) access, so a true security breach would require the rogue class belong to the same package or override access checking. Thus, a security model that prevents the addition of rogue classes to a package during the life of the VM/ClassLoader and that prevents overriding accessibility checks would safely thwart all attempts to breach a package from outside; then it is just a matter of only having trusted code within the package. ======== import java.lang.reflect.*; public class Synthetic { public static void main(String[] args) { try { // the XXX.class access generates synthetic blank finals, and class$() output("methods in Synthetic", Synthetic.class.getDeclaredMethods()); output("fields in Synthetic", Synthetic.class.getDeclaredFields()); output("constructors in Synthetic", Synthetic.class.getDeclaredConstructors()); output("classes in Synthetic", Synthetic.class.getDeclaredClasses()); output("methods in Sub", Sub.class.getDeclaredMethods()); output("fields in Sub", Sub.class.getDeclaredFields()); output("constructors in Sub", Sub.class.getDeclaredConstructors()); output("classes in Sub", Sub.class.getDeclaredClasses()); // invoke the synthetic class$() method on a completely unrelated class! System.out.println(Synthetic.class .getDeclaredMethod("class$", new Class[] {String.class}) .invoke(null, new Object[] {"java.lang.Integer"} )); // constructing a Sub generates a synthetic class in JDK1.3 System.out.println("Sub contains " + new Synthetic().new Sub()); } catch (Exception e) { } } // a default constructor is generated, but this is not synthetic // Synthetic() {} // i must be a private, non-constant to generate synthetic accessor method private int i = 1 + 2; class Sub { // private constructor requires synthetic constructor to access private Sub() {} public String toString() { return ""+i; } } static void output(String prefix, Object[] array) { System.out.print(prefix + ":\n[" + (array.length > 0 ? array[0] : "")); for (int i=1; i<array.length; i++) System.out.print(",\n " + array[i]); System.out.println("]"); } } ========= output of Synthetic: methods in Synthetic [public static void Synthetic.main(java.lang.String[]), static int Synthetic.access$100(Synthetic), //synthetic static java.lang.Class Synthetic.class$(java.lang.String), //synthetic static void Synthetic.output(java.lang.Object[])] fields in Synthetic [private int Synthetic.i, static java.lang.Class Synthetic.class$Synthetic, //synthetic static java.lang.Class Synthetic.class$Synthetic$Sub, //synthetic static java.lang.Class Synthetic.class$java$lang$String] //synthetic constructors in Synthetic [public Synthetic()] // although this is generated, it is not synthetic classes in Synthetic [class Synthetic$1, //synthetic class Synthetic$Sub] methods in Sub [public java.lang.String Synthetic$Sub.toString()] fields in Sub [private final Synthetic Synthetic$Sub.this$0] //synthetic constructors in Sub [Synthetic$Sub(Synthetic,Synthetic$1), //synthetic private Synthetic$Sub(Synthetic)] classes in Sub [] class java.lang.Integer // We just abused the class$() method Sub contains 3 =========== import java.lang.reflect.*; public class Breach { public static void main(String[] args) { try { Method m = Synthetic.class .getDeclaredMethod("access$100", new Class[] {Synthetic.class} ); Synthetic s = new Synthetic(); System.out.println("I just read the private field Synthetic.i: " + m.invoke(s, new Object[] {s} )); } catch (Exception e) { System.out.println("Caught: " + e); } } } ========= output of Breach: I just read the private field Synthetic.i: 3 (Review ID: 108233) ======================================================================
|