Author: markt
Date: Sat Jan 27 16:55:24 2007
New Revision: 500716

URL: http://svn.apache.org/viewvc?view=rev&rev=500716
Log:
Port fix bug 39088 that prevents infinite loops when an exception is thrown the 
returns itself for getRootCause(). Also port changes that enable the root cause 
to be found when the nesting is particularly extreme.

Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java?view=diff&rev=500716&r1=500715&r2=500716
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardWrapper.java Sat 
Jan 27 16:55:24 2007
@@ -31,6 +31,8 @@
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.sql.SQLException;
+
 import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -60,6 +62,7 @@
 import org.apache.catalina.security.SecurityUtil;
 import org.apache.catalina.util.Enumerator;
 import org.apache.catalina.util.InstanceSupport;
+import org.apache.tomcat.util.IntrospectionUtils;
 import org.apache.tomcat.util.log.SystemLogHandler;
 import org.apache.tomcat.util.modeler.Registry;
 
@@ -291,7 +294,19 @@
      */
     protected static Properties restrictedServlets = null;
     
+
+    private static Class jspExceptionClazz;
     
+    static {
+        try {
+            jspExceptionClazz = 
Class.forName("javax.servlet.jsp.JspException");
+        } catch (ClassNotFoundException e) {
+            // Expected if jsp-api not on classpath, eg when embedding
+            jspExceptionClazz = null;
+        }
+    }
+
+
     // ------------------------------------------------------------- Properties
 
 
@@ -675,18 +690,41 @@
      * @param e The servlet exception
      */
     public static Throwable getRootCause(ServletException e) {
-        Throwable rootCause = e;
-        Throwable rootCauseCheck = null;
-        // Extra aggressive rootCause finding
-        int loops = 0;
-        do {
-            loops++;
-            rootCauseCheck = rootCause.getCause();
-            if (rootCauseCheck != null)
-                rootCause = rootCauseCheck;
-        } while (rootCauseCheck != null && (loops < 20));
-        return rootCause;
+        Throwable rootCause = e.getRootCause();
+        return findRootCause(e, rootCause);
     }
+
+
+    /*
+     * Work through the root causes using specific methods for well known types
+     * and getCause() for the rest. Stop when the next rootCause is null or
+     * an exception is found that has itself as its own rootCause. 
+     */
+    private static final Throwable findRootCause(Throwable theException,
+            Throwable theRootCause) {
+        
+        Throwable deeperRootCause = null;
+
+        if (theRootCause == null || theRootCause == theException) {
+            return theException;
+        }
+        
+        if (theRootCause instanceof ServletException) {
+            deeperRootCause = ((ServletException) theRootCause).getRootCause();
+        } else if (jspExceptionClazz!=null &&
+                jspExceptionClazz.isAssignableFrom(theRootCause.getClass())) {
+            deeperRootCause = (Throwable)IntrospectionUtils.getProperty(
+                    theRootCause, "rootCause"); 
+        } else if (theRootCause instanceof SQLException) {
+            deeperRootCause = ((SQLException) theRootCause).getNextException();
+        }
+        if (deeperRootCause == null) {
+            deeperRootCause = theRootCause.getCause();
+        }
+        
+        return findRootCause(theRootCause, deeperRootCause);
+    }
+
 
 
     /**

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?view=diff&rev=500716&r1=500715&r2=500716
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/valves/ErrorReportValve.java 
Sat Jan 27 16:55:24 2007
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.io.Writer;
+import java.sql.SQLException;
 
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
@@ -33,6 +34,7 @@
 import org.apache.catalina.util.RequestUtil;
 import org.apache.catalina.util.ServerInfo;
 import org.apache.catalina.util.StringManager;
+import org.apache.tomcat.util.IntrospectionUtils;
 
 /**
  * <p>Implementation of a Valve that outputs HTML error pages.</p>
@@ -71,6 +73,18 @@
         StringManager.getManager(Constants.Package);
 
 
+    private static Class jspExceptionClazz;
+
+    static {
+        try {
+            jspExceptionClazz = 
Class.forName("javax.servlet.jsp.JspException");
+        } catch (ClassNotFoundException e) {
+            // Expected if jsp-api not on classpath, eg when embedding
+            jspExceptionClazz = null;
+        }
+    }
+    
+    
     // ------------------------------------------------------------- Properties
 
 
@@ -216,9 +230,9 @@
             sb.append(RequestUtil.filter(stackTrace));
             sb.append("</pre></p>");
 
-            int loops = 0;
             Throwable rootCause = throwable.getCause();
-            while (rootCause != null && (loops < 10)) {
+            Throwable nestedRootCause = null;
+            while (rootCause != null) {
                 stackTrace = getPartialServletStackTrace(rootCause);
                 sb.append("<p><b>");
                 sb.append(sm.getString("errorReportValve.rootCause"));
@@ -226,10 +240,33 @@
                 sb.append(RequestUtil.filter(stackTrace));
                 sb.append("</pre></p>");
                 // In case root cause is somehow heavily nested
-                rootCause = rootCause.getCause();
-                loops++;
+                try {
+                    if (rootCause instanceof ServletException) {
+                        nestedRootCause =
+                            ((ServletException) rootCause).getRootCause();
+                    } else if (jspExceptionClazz!=null &&
+                            jspExceptionClazz.isAssignableFrom(
+                                    rootCause.getClass())) {
+                        nestedRootCause = (Throwable)IntrospectionUtils.
+                                getProperty(rootCause, "rootCause"); 
+                    } else if (rootCause instanceof SQLException) {
+                        nestedRootCause = ((SQLException) rootCause).
+                                getNextException();
+                    }
+                    if (nestedRootCause == null) {
+                        nestedRootCause = rootCause.getCause();
+                    }
+
+                    if (rootCause == nestedRootCause)
+                        rootCause = null;
+                    else {
+                        rootCause = nestedRootCause;
+                        nestedRootCause = null;
+                    }
+                } catch (ClassCastException e) {
+                    rootCause = null;
+                }
             }
-
             sb.append("<p><b>");
             sb.append(sm.getString("errorReportValve.note"));
             sb.append("</b> <u>");

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?view=diff&rev=500716&r1=500715&r2=500716
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Sat Jan 27 16:55:24 2007
@@ -31,6 +31,10 @@
         web.xml. (markt)
       </fix>
       <fix>
+        <bug>39088</bug>: Prevent infinte loops when an exception is thrown
+        that returns itself for getRootCause(). (markt)
+      </fix>
+      <fix>
         <bug>41217</bug>: Set secure attribute on SSO cookie when cookie is
         created during a secure request. Patch provided by Chris Halstead.
         (markt)



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to