This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: problem with class accessiblity check in invoke (natMethod.cc)
Hello Andrew,
Thanks for your quick reply. We include code below.
On Wed, Dec 23, 2009 at 11:46, Andrew Haley <aph@redhat.com> wrote:
> On 12/23/2009 10:38 AM, Erik Groeneveld wrote:
>
[...]
>> Â Â Â else
>> Â Â Â // Method is public, check to see if class is accessible.
>> Â Â Â {
>> Â Â Â Â jint flags = (declaringClass->accflags
>> Â Â Â Â Â Â Â Â Â Â Â & (Modifier::PUBLIC
>> Â Â Â Â Â Â Â Â Â Â Â Â Â| Modifier::PROTECTED
>> Â Â Â Â Â Â Â Â Â Â Â Â Â| Modifier::PRIVATE));
>> Â Â Â Â if (flags == 0) // i.e. class is package private
>> Â Â Â Â Â {
>> Â Â Â Â Â Â Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
>> Â Â Â Â Â Â if (! _Jv_ClassNameSamePackage (caller->name,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â declaringClass->name))
>> Â Â Â Â Â Â Â throw new IllegalAccessException;
>> Â Â Â Â Â }
>> Â Â Â }
>> Â Â }
>>
[...]
>> 1. The systems segfaults on the caller->name because there is no calling class.
>
> How can there be no calling class?
Because we call it from C++ not from Java. We forgot to mention that.
>> 2. We believe class accessibility is not relevant here: there is no
>> reason why a Method object with public access should not be invokable,
>> or is there?
[...]
>
> Yes, but can you send a test case before we go any further? ÂThen at least
> we'll all know what you're talking about.
The following code demonstrates the problem.
#include <gcj/cni.h>
#include <java/util/ArrayList.h>
#include <java/util/Iterator.h>
#include <java/lang/reflect/Method.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
JvCreateJavaVM(NULL);
JvAttachCurrentThread(NULL, NULL);
java::util::ArrayList* l = new java::util::ArrayList();
java::util::Iterator* i = l->iterator();
java::lang::reflect::Method* m = i->getClass()->getDeclaredMethod(
JvNewStringUTF("hasNext"), NULL);
printf("calling invoke, it'll dump core in natMethod.cc line 194\n");
m->invoke(i, NULL);
return 0;
}
$gcc problem.cpp -lgcj
$./a.out
calling invoke
Aborted (core dumped)
$gdb -core core a.out
(gdb) where
#0 0x00002adf9252bed5 in raise () from /lib/libc.so.6
#1 0x00002adf9252d3f3 in abort () from /lib/libc.so.6
#2 0x00002adf90bdeed8 in _Jv_Throw (value=0x2adf932cd370) at
../../../src/libjava/exception.cc:128
#3 0x00002adf90bd2a2a in _Jv_catch_segv (_p=<value optimized out>) at
../../../src/libjava/prims.cc:184
#4 <signal handler called>
#5 0x00002adf90c217d3 in java::lang::reflect::Method::invoke
(this=0x2adf932d1c80, obj=0x2adf93ba6e40,
args=0x0) at ../../../src/libjava/java/lang/reflect/natMethod.cc:194
#6 0x0000000000400a5c in main ()
The top of the stack is from the NULL-pointer catching signal handler
we believe, so #5 and #6 are the relevant ones.
The point is that we believe that the scenario in the C++ code is
valid, both from Java and from C++, and we do not see the reasons for
the additional check that has been added to the invoke() method.
Erik
Jurjan-Paul