This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[BC] Patch: FYI: access checks for overriding
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 01 Sep 2004 13:42:26 -0600
- Subject: [BC] Patch: FYI: access checks for overriding
- Reply-to: tromey at redhat dot com
I'm checking this in on the BC branch.
This fixes a few bugs involving access checking and vtable layout.
First, it is valid to use Method.invoke on a private method if the
caller has ordinary access to it. I added a Mauve test for this.
Second, a method does not override a package-private method in another
package. I added a Mauve test for this as well.
Likewise, a method does not override a static method.
And, finally, overriding a final method is a verification error.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* java/lang/reflect/natMethod.cc (invoke): Check access against
declaring class, not object's class.
* java/lang/natClass.cc (_Jv_LookupDeclaredMethod): Added another
argument.
(_Jv_LayoutVTableMethods): Perform checks of accessibility of
overridden method.
* java/lang/Class.h (_Jv_LookupDeclaredMethod): Added another
argument.
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.63.12.7
diff -u -r1.63.12.7 Class.h
--- java/lang/Class.h 27 Aug 2004 19:54:23 -0000 1.63.12.7
+++ java/lang/Class.h 1 Sep 2004 19:48:51 -0000
@@ -306,7 +306,8 @@
friend int _Jv_LayoutClass(jclass);
friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
- _Jv_Utf8Const*);
+ _Jv_Utf8Const*,
+ jclass * = 0);
friend jfieldID JvGetFirstInstanceField (jclass);
friend jint JvNumInstanceFields (jclass);
friend jfieldID JvGetFirstStaticField (jclass);
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.75.2.11
diff -u -r1.75.2.11 natClass.cc
--- java/lang/natClass.cc 30 Aug 2004 15:45:25 -0000 1.75.2.11
+++ java/lang/natClass.cc 1 Sep 2004 19:48:51 -0000
@@ -939,14 +939,19 @@
_Jv_Method *
_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
- _Jv_Utf8Const *signature)
+ _Jv_Utf8Const *signature,
+ jclass *declarer_result)
{
for (; klass; klass = klass->getSuperclass())
{
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
if (meth)
- return meth;
+ {
+ if (declarer_result)
+ *declarer_result = klass;
+ return meth;
+ }
}
return NULL;
@@ -2078,16 +2083,31 @@
if (! _Jv_isVirtualMethod (meth))
continue;
- // FIXME: Must check that we don't override:
- // - Package-private method where superclass is in different package.
- // - Final or less-accessible declaration in superclass (check binary
- // spec, do we allocate new vtable entry or put throw node in vtable?)
- // - Static or private method in superclass.
-
if (superclass != NULL)
{
+ jclass declarer;
super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name,
- meth->signature);
+ meth->signature, &declarer);
+ // See if this method actually overrides the other method
+ // we've found.
+ if (super_meth)
+ {
+ if (! _Jv_isVirtualMethod (super_meth)
+ || ! _Jv_CheckAccess (klass, declarer,
+ super_meth->accflags))
+ super_meth = NULL;
+ else if ((super_meth->accflags
+ & java::lang::reflect::Modifier::FINAL) != 0)
+ {
+ using namespace java::lang;
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1("method "));
+ sb->append(_Jv_GetMethodString(klass, meth->name));
+ sb->append(JvNewStringLatin1(" overrides final method "));
+ sb->append(_Jv_GetMethodString(declarer, super_meth->name));
+ throw new VerifyError(sb->toString());
+ }
+ }
}
if (super_meth)
Index: java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.37.4.3
diff -u -r1.37.4.3 natMethod.cc
--- java/lang/reflect/natMethod.cc 20 May 2004 23:34:05 -0000 1.37.4.3
+++ java/lang/reflect/natMethod.cc 1 Sep 2004 19:48:51 -0000
@@ -1,6 +1,6 @@
// natMethod.cc - Native code for Method class.
-/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -149,7 +149,6 @@
getType ();
jmethodID meth = _Jv_FromReflectedMethod (this);
- jclass objClass;
if (Modifier::isStatic(meth->accflags))
{
@@ -157,12 +156,10 @@
// here and not in _Jv_CallAnyMethodA because JNI initializes a
// class whenever a method lookup is done.
_Jv_InitClass (declaringClass);
- objClass = declaringClass;
}
else
{
- objClass = JV_CLASS (obj);
-
+ jclass objClass = JV_CLASS (obj);
if (! _Jv_IsAssignableFrom (declaringClass, objClass))
throw new java::lang::IllegalArgumentException;
}
@@ -184,7 +181,7 @@
{
}
- if (! _Jv_CheckAccess(caller, objClass, meth->accflags))
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
throw new IllegalAccessException;
}