Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Mon, 12 Dec 2005 13:21:59 +0900 (JST) > Sun's JDK (the test programs compiled with ecj): > > Call a private constructor in the same class > OK > Call a private constructor in the same pakeage > OK (*3) > Call a private constructor in another pakeage > java.lang.IllegalAccessException: Class A can not access a member of class > b.B$PrivateClass with modifiers "" > >(*3) Ecj fails to put the private flag to the constructor. This is not a issue of Kaffe, but just for your reference, I found this bug reported in https://bugs.eclipse.org/bugs/show_bug.cgi?id=77473 and the following seems to be due to the same bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=117758 ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Mon, 12 Dec 2005 15:21:26 +0900 (JST) > But I am afraid > >266 else if( (target->name->data[0] != '[') && >267 same_package && >268 (target->this_inner_index >= 0) ) >269 { >270 slot_acc = 1; >271 } > > will make something private in the target class T accessible to > the caller C if T and C are in the same package and T is a nested > class. How about this patch? --- kaffe/kaffevm/access.c.orig Fri Aug 19 15:00:41 2005 +++ kaffe/kaffevm/access.c Mon Dec 12 16:37:15 2005 @@ -153,6 +153,45 @@ } } +/* + * Returns 1 if oc is an outer class of c + */ +static +int outerof (Hjava_lang_Class *c, Hjava_lang_Class *oc) +{ + innerClass *ic; + Hjava_lang_Class *outer; + errorInfo einfo; + + outer = NULL; + if( c->this_inner_index >= 0 ) + { + ic = &c->inner_classes[c->this_inner_index]; + if( ic->outer_class ) + { + outer = getClass(ic->outer_class, c, &einfo); + if( outer == NULL ) + { + discardErrorInfo(&einfo); + } + } + } + if ( outer != NULL ) + { + if ( oc == outer) + { + return 1; + } + else + { + return outerof(outer, oc); + } + } + else { + return 0; + } +} + int checkAccess(struct Hjava_lang_Class *context, struct Hjava_lang_Class *target, accessFlags target_flags) @@ -236,6 +275,14 @@ } } + else if ( outerof(target, context) ) + { + /* target is within the context. */ + class_acc = 1; + slot_acc = 1; + + return 1; + } if((context->packageLength == target->packageLength) && !strncmp(context->name->data, @@ -263,12 +310,17 @@ /* Package. */ slot_acc = 1; } +/* + Commented out because private members get accessible to + any context in the same package if target is a nested class. + else if( (target->name->data[0] != '[') && same_package && (target->this_inner_index >= 0) ) { slot_acc = 1; } +*/ else if( context->this_inner_index >= 0 ) { innerClass *ic; ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Mon, 12 Dec 2005 11:35:59 +0900 (JST) > kaffe/kaffevm/access.c has this code: > >261 else if( same_package && !(target_flags & ACC_PRIVATE) ) >262 { >263 /* Package. */ >264 slot_acc = 1; >265 } > I am afraid this makes anything private in the target class T > accessible to the caller C if T and C are in the same package > and T is accessible to C. This is not the case thanks to the "!" of "!(target_flags & ACC_PRIVATE)". But I am afraid 266 else if( (target->name->data[0] != '[') && 267 same_package && 268 (target->this_inner_index >= 0) ) 269 { 270 slot_acc = 1; 271 } will make something private in the target class T accessible to the caller C if T and C are in the same package and T is a nested class. ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Mon, 12 Dec 2005 11:35:59 +0900 (JST) > kaffe/kaffevm/access.c has this code: > >261 else if( same_package && !(target_flags & ACC_PRIVATE) ) >262 { >263 /* Package. */ >264 slot_acc = 1; >265 } > > I am afraid this makes anything private in the target class T > accessible to the caller C if T and C are in the same package > and T is accessible to C. Sorry, I missed the "!". ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
The test case attached below gives interesting results when run on various environments. It seems that kaffe, Sun's JDK, and ecj have some problem of their own. Kaffe: Call a private constructor in the same class OK Call a private constructor in the same pakeage OK (*1) Call a private constructor in another pakeage java.lang.IllegalAccessException (*1) Maybe a bug in kaffe/kaffevm/access.c Sun's JDK (the test programs compiled with Sun's javac): Call a private constructor in the same class java.lang.IllegalAccessException: Class A can not access a member of class A$PrivateClass with modifiers "private" (*2) Call a private constructor in the same pakeage java.lang.IllegalAccessException: Class A can not access a member of class B$PrivateClass with modifiers "private" Call a private constructor in another pakeage java.lang.IllegalAccessException: Class A can not access a member of class b.B$PrivateClass with modifiers "private" (*2) JDK seems to be missing the fact that the target is declared within the caller. Sun's JDK (the test programs compiled with ecj): Call a private constructor in the same class OK Call a private constructor in the same pakeage OK (*3) Call a private constructor in another pakeage java.lang.IllegalAccessException: Class A can not access a member of class b.B$PrivateClass with modifiers "" (*3) Ecj fails to put the private flag to the constructor. The source of the test case follows. $ cat A.java public class A { private static class PrivateClass { private PrivateClass() {} } public static void main(String[] args) { System.err.println("Call a private constructor in the same class"); try { PrivateClass.class.newInstance(); System.err.println("OK"); } catch (Exception e) { System.err.println(e); } System.err.println("Call a private constructor in the same pakeage"); try { B.getPrivateClass().newInstance(); System.err.println("OK"); } catch (Exception e) { System.err.println(e); } System.err.println("Call a private constructor in another pakeage"); try { b.B.getPrivateClass().newInstance(); System.err.println("OK"); } catch (Exception e) { System.err.println(e); } } } $cat B.java public class B { private static class PrivateClass { private PrivateClass() {} } public static Class getPrivateClass() { return PrivateClass.class; } } $cat b/B.java package b; public class B { private static class PrivateClass { private PrivateClass() {} } public static Class getPrivateClass() { return PrivateClass.class; } } ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Sun, 11 Dec 2005 10:51:52 +0900 (JST) > The next test case will illustrate this problem more clearly. > > $ cat A.java > public class A { > public static void main(String[] args) { > try { > B.getPrivateClass().newInstance(); > } > catch (Exception e) { > e.printStackTrace(); > } > } > > } > $ cat B.java > public class B { > private static class PrivateClass {} > public static Class getPrivateClass() { return PrivateClass.class; } > } > > In this case, Sun's JDK throws IllegalAccessException as expected. > But Kaffe does not. kaffe/kaffevm/access.c has this code: 261 else if( same_package && !(target_flags & ACC_PRIVATE) ) 262 { 263 /* Package. */ 264 slot_acc = 1; 265 } I am afraid this makes anything private in the target class T accessible to the caller C if T and C are in the same package and T is accessible to C. ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe
Re: [kaffe] Should IllegalAccessException be thrown or not?
From: Ito Kazumitsu <[EMAIL PROTECTED]> Date: Sat, 10 Dec 2005 11:18:13 +0900 (JST) > public class TestPrivateClass { > private static class Test0001 { > } > > public static void main(String[] args) { > try { > Object obj = Test0001.class.newInstance(); > } > catch (Exception e) { > e.printStackTrace(); > } > } > } > > This ends normally when run on Kaffe, but when run on Sun's JDK, > > java.lang.IllegalAccessException: Class TestPrivateClass can not access a > member of class TestPrivateClass$Test0001 with modifiers "private" According to "8.8.9 Default Constructor" in The Java Language Specification, if the class is declared private, then the default constructor is implicitly given the access modifier private. So IllegalAccessException should be thrown. The next test case will illustrate this problem more clearly. $ cat A.java public class A { public static void main(String[] args) { try { B.getPrivateClass().newInstance(); } catch (Exception e) { e.printStackTrace(); } } } $ cat B.java public class B { private static class PrivateClass {} public static Class getPrivateClass() { return PrivateClass.class; } } In this case, Sun's JDK throws IllegalAccessException as expected. But Kaffe does not. ___ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe