This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[BC] Patch: FYI: access checks for overriding


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;
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]