Author: markt
Date: Fri Jan 17 15:37:20 2014
New Revision: 1559153

URL: http://svn.apache.org/r1559153
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55943
Better implementation of the class loader check that prevents web applications 
from trying to override J2SE implementation classes.
Refactor the way a null parent class loader was handled which enables a number 
of null checks and object creation calls to be removed

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1559134

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1559153&r1=1559152&r2=1559153&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java 
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/loader/WebappClassLoader.java 
Fri Jan 17 15:37:20 2014
@@ -227,14 +227,26 @@ public class WebappClassLoader
     public WebappClassLoader() {
 
         super(new URL[0]);
-        this.parent = getParent();
-        system = getSystemClassLoader();
-        securityManager = System.getSecurityManager();
 
+        ClassLoader p = getParent();
+        if (p == null) {
+            p = getSystemClassLoader();
+        }
+        this.parent = p;
+
+        ClassLoader j = String.class.getClassLoader();
+        if (j == null) {
+            j = getSystemClassLoader();
+            while (j.getParent() != null) {
+                j = j.getParent();
+            }
+        }
+        this.j2seClassLoader = j;
+
+        securityManager = System.getSecurityManager();
         if (securityManager != null) {
             refreshPolicy();
         }
-
     }
 
 
@@ -251,11 +263,22 @@ public class WebappClassLoader
 
         super(new URL[0], parent);
 
-        this.parent = getParent();
+        ClassLoader p = getParent();
+        if (p == null) {
+            p = getSystemClassLoader();
+        }
+        this.parent = p;
 
-        system = getSystemClassLoader();
-        securityManager = System.getSecurityManager();
+        ClassLoader j = String.class.getClassLoader();
+        if (j == null) {
+            j = getSystemClassLoader();
+            while (j.getParent() != null) {
+                j = j.getParent();
+            }
+        }
+        this.j2seClassLoader = j;
 
+        securityManager = System.getSecurityManager();
         if (securityManager != null) {
             refreshPolicy();
         }
@@ -413,6 +436,15 @@ public class WebappClassLoader
 
 
     /**
+     * The bootstrap class loader used to load the J2SE classes. In some
+     * implementations this class loader is always <code>null</null> and in
+     * those cases {@link ClassLoader#getParent()} will be called recursively 
on
+     * the system class loader and the last non-null result used.
+     */
+    protected final ClassLoader j2seClassLoader;
+
+
+    /**
      * Has this component been started?
      */
     protected boolean started = false;
@@ -1396,10 +1428,7 @@ public class WebappClassLoader
         if (delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            url = loader.getResource(name);
+            url = parent.getResource(name);
             if (url != null) {
                 if (log.isDebugEnabled())
                     log.debug("  --> Returning '" + url.toString() + "'");
@@ -1433,10 +1462,7 @@ public class WebappClassLoader
 
         // (3) Delegate to parent unconditionally if not already attempted
         if( !delegate ) {
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            url = loader.getResource(name);
+            url = parent.getResource(name);
             if (url != null) {
                 if (log.isDebugEnabled())
                     log.debug("  --> Returning '" + url.toString() + "'");
@@ -1480,10 +1506,7 @@ public class WebappClassLoader
         if (delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            stream = loader.getResourceAsStream(name);
+            stream = parent.getResourceAsStream(name);
             if (stream != null) {
                 // FIXME - cache???
                 if (log.isDebugEnabled())
@@ -1515,10 +1538,7 @@ public class WebappClassLoader
         if (!delegate) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader unconditionally 
" + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
-            stream = loader.getResourceAsStream(name);
+            stream = parent.getResourceAsStream(name);
             if (stream != null) {
                 // FIXME - cache???
                 if (log.isDebugEnabled())
@@ -1617,7 +1637,7 @@ public class WebappClassLoader
         // (0.2) Try loading the class with the system class loader, to prevent
         //       the webapp from overriding J2SE classes
         try {
-            clazz = system.loadClass(name);
+            clazz = j2seClassLoader.loadClass(name);
             if (clazz != null) {
                 if (resolve)
                     resolveClass(clazz);
@@ -1648,11 +1668,8 @@ public class WebappClassLoader
         if (delegateLoad) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader1 " + parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
             try {
-                clazz = Class.forName(name, false, loader);
+                clazz = Class.forName(name, false, parent);
                 if (clazz != null) {
                     if (log.isDebugEnabled())
                         log.debug("  Loading class from parent");
@@ -1685,11 +1702,8 @@ public class WebappClassLoader
         if (!delegateLoad) {
             if (log.isDebugEnabled())
                 log.debug("  Delegating to parent classloader at end: " + 
parent);
-            ClassLoader loader = parent;
-            if (loader == null)
-                loader = system;
             try {
-                clazz = Class.forName(name, false, loader);
+                clazz = Class.forName(name, false, parent);
                 if (clazz != null) {
                     if (log.isDebugEnabled())
                         log.debug("  Loading class from parent");

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1559153&r1=1559152&r2=1559153&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jan 17 15:37:20 2014
@@ -71,6 +71,13 @@
         <code>/ROOT</code> as equivalent to <code>/</code>. (markt)
       </fix>
       <fix>
+        <bug>55943</bug>: Improve the implementation of the class loader check
+        that prevents web applications from trying to override J2SE
+        implementation classes. As part of this fix, refactor the way a null
+        parent class loader is handled which enables a number of null checks 
and
+        object creation calls to be removed. (markt)
+      </fix>
+      <fix>
         <bug>55958</bug>: Differentiate between <code>foo.war</code> the WAR
         file and <code>foo.war</code> the directory. (markt)
       </fix>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to