BootClassLoader.java (getBootURLLoader): New method.
authorAndrew Haley <aph@redhat.com>
Mon, 16 Apr 2007 13:44:59 +0000 (13:44 +0000)
committerAndrew Haley <aph@gcc.gnu.org>
Mon, 16 Apr 2007 13:44:59 +0000 (13:44 +0000)
2007-04-16  Andrew Haley  <aph@redhat.com>

        * gnu/gcj/runtime/BootClassLoader.java (getBootURLLoader): New
        method.
        (bootGetResource): Use getBootURLLoader() to load resources.
        (bootGetResources): Likewise.

        * java/lang/reflect/natMethod.cc (Method::invoke): In invoke also
        check that the method's declaring class is accessible.

From-SVN: r123862

libjava/ChangeLog
libjava/gnu/gcj/runtime/BootClassLoader.java
libjava/java/lang/reflect/natMethod.cc

index d5f0255..31bbd01 100644 (file)
@@ -1,3 +1,13 @@
+2007-04-16  Andrew Haley  <aph@redhat.com>
+
+       * gnu/gcj/runtime/BootClassLoader.java (getBootURLLoader): New
+       method.
+       (bootGetResource): Use getBootURLLoader() to load resources.
+       (bootGetResources): Likewise.
+
+       * java/lang/reflect/natMethod.cc (Method::invoke): In invoke also
+       check that the method's declaring class is accessible.
+
 2007-04-10  Keith Seitz  <keiths@redhat.com>
 
        * sources.am: Regenerate.
index 731703a..40f3147 100644 (file)
@@ -9,9 +9,13 @@ details.  */
 package gnu.gcj.runtime;
 
 import gnu.java.net.protocol.core.Handler;
+import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
 
 /**
  * This is a helper for the bootstrap class loader.  It is a
@@ -27,6 +31,9 @@ public final class BootClassLoader extends HelperClassLoader
   // path fails otherwise.
   static Class coreHandler = gnu.java.net.protocol.core.Handler.class;
 
+  private boolean initialized;
+  private URLClassLoader bootURLLoader;
+
   BootClassLoader(String libdir)
   {
     // The BootClassLoader is the top of the delegation chain. It does not
@@ -68,13 +75,64 @@ public final class BootClassLoader extends HelperClassLoader
     return c;
   }
 
+  // Parse the boot classpath and create a URLClassLoader that loads
+  // resources from it.  This is provided for the benefit of code that
+  // does things like
+  //   ClassLoader.getResourceAsStream("java/lang/Object.class")
+  private synchronized URLClassLoader getBootURLLoader()
+  {
+    if (initialized)
+      return bootURLLoader;
+    initialized = true;
+
+    Vector<URL> urls = new Vector<URL>();
+    String bootClasspath = System.getProperty ("sun.boot.class.path");
+    StringTokenizer st =
+      new StringTokenizer(bootClasspath, File.pathSeparator);
+    while (st.hasMoreTokens())
+      {
+       try
+         {
+           urls.add(new File(st.nextToken()).toURL());
+         }
+       catch (java.net.MalformedURLException e)
+         {
+         }
+      }
+
+    if (urls.size() > 0)
+      bootURLLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
+    return bootURLLoader;
+  }
+
   public URL bootGetResource(String name)
   {
-    return findResource(name);
+    URL url = findResource(name);
+    if (url != null)
+      return url;
+
+    URLClassLoader loader = getBootURLLoader();
+    if (loader != null)
+      url = loader.findResource(name);
+
+    return url;
   }
 
   public Enumeration bootGetResources(String name) throws IOException
   {
-    return findResources(name);
+    URLClassLoader loader = getBootURLLoader();
+    Enumeration[] e =
+      {
+       findResources(name),
+       (loader != null) ? loader.findResources(name) : null
+      };
+
+    Vector v = new Vector();
+    for (Enumeration en : e)
+      if (en != null)
+       while (en.hasMoreElements())
+         v.add(en.nextElement());
+
+    return v.elements();
   }
 }
index 6dcd4ec..4593da7 100644 (file)
@@ -173,16 +173,34 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
     }
 
   // Check accessibility, if required.
-  if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+  if (! this->isAccessible())
     {
-      Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
-      if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
-       throw new IllegalAccessException;
+      if (! (Modifier::isPublic (meth->accflags)))
+       {
+         Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+         if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+           throw new IllegalAccessException;
+       }
+      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;
+           }
+       }
     }
 
   if (declaringClass->isInterface())
     iface = declaringClass;
-  
+
   return _Jv_CallAnyMethodA (obj, return_type, meth, false,
                             parameter_types, args, iface);
 }