You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/09/28 11:54:25 UTC

svn commit: r1809978 - in /tomcat/tc7.0.x/trunk/java/org/apache/naming/resources: FileDirContext.java JrePlatform.java

Author: markt
Date: Thu Sep 28 11:54:25 2017
New Revision: 1809978

URL: http://svn.apache.org/viewvc?rev=1809978&view=rev
Log:
First pass at aligning 7.0.x checks with 8.0.x

Added:
    tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/JrePlatform.java
      - copied, changed from r1809922, tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/compat/JrePlatform.java
Modified:
    tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java

Modified: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java?rev=1809978&r1=1809977&r2=1809978&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/FileDirContext.java Thu Sep 28 11:54:25 2017
@@ -14,8 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-
 package org.apache.naming.resources;
 
 import java.io.File;
@@ -97,6 +95,8 @@ public class FileDirContext extends Base
      */
     protected String absoluteBase = null;
 
+    private String canonicalBase = null;
+
 
     /**
      * Allow linking.
@@ -106,7 +106,6 @@ public class FileDirContext extends Base
 
     // ------------------------------------------------------------- Properties
 
-
     /**
      * Set the document root.
      *
@@ -137,14 +136,14 @@ public class FileDirContext extends Base
             throw new IllegalArgumentException(sm.getString("fileResources.base", docBase));
         }
 
+        this.absoluteBase = normalize(base.getAbsolutePath());
+
         // absoluteBase also needs to be normalized. Using the canonical path is
         // the simplest way of doing this.
         try {
-            this.absoluteBase = base.getCanonicalPath();
+            this.canonicalBase = base.getCanonicalPath();
         } catch (IOException e) {
-            log.warn(sm.getString("fileResources.canonical.fail", base.getPath()));
-            // Fall back to the absolute path
-            this.absoluteBase = base.getAbsolutePath();
+            throw new IllegalArgumentException(e);
         }
         super.setDocBase(docBase);
     }
@@ -827,8 +826,15 @@ public class FileDirContext extends Base
 
         // If allow linking is enabled, files are not limited to being located
         // under the fileBase so all further checks are disabled.
-        if (allowLinking)
+        if (allowLinking) {
             return file;
+        }
+
+        // Additional Windows specific checks to handle known problems with
+        // File.getCanonicalPath()
+        if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) {
+            return null;
+        }
 
         // Check that this file is located under the web application root
         String canPath = null;
@@ -837,17 +843,16 @@ public class FileDirContext extends Base
         } catch (IOException e) {
             // Ignore
         }
-        if (canPath == null || !canPath.startsWith(absoluteBase)) {
+        if (canPath == null || !canPath.startsWith(canonicalBase)) {
             return null;
         }
 
         // Ensure that the file is not outside the fileBase. This should not be
         // possible for standard requests (the request is normalized early in
         // the request processing) but might be possible for some access via the
-        // Servlet API (RequestDispatcher, HTTP/2 push etc.) therefore these
-        // checks are retained as an additional safety measure
-        // absoluteBase has been normalized so absPath needs to be normalized as
-        // well.
+        // Servlet API (RequestDispatcheretc.) therefore these checks are
+        // retained as an additional safety measure absoluteBase has been
+        // normalized so absPath needs to be normalized as well.
         String absPath = normalize(file.getAbsolutePath());
         if ((absoluteBase.length() > absPath.length())) {
             return null;
@@ -857,7 +862,7 @@ public class FileDirContext extends Base
         // was not part of the requested path and the remaining check only
         // applies to the request path
         absPath = absPath.substring(absoluteBase.length());
-        canPath = canPath.substring(absoluteBase.length());
+        canPath = canPath.substring(canonicalBase.length());
 
         // Case sensitivity check
         // The normalized requested path should be an exact match the equivalent
@@ -870,9 +875,8 @@ public class FileDirContext extends Base
         //
         // absPath is normalized so canPath needs to be normalized as well
         // Can't normalize canPath earlier as canonicalBase is not normalized
-        canPath = normalize(canPath);
-        if (absPath.length() == 0) {
-            absPath = "/";
+        if (canPath.length() > 0) {
+            canPath = normalize(canPath);
         }
         if (!canPath.equals(absPath)) {
             return null;
@@ -882,6 +886,36 @@ public class FileDirContext extends Base
     }
 
 
+    private boolean isInvalidWindowsFilename(String name) {
+        final int len = name.length();
+        if (len == 0) {
+            return false;
+        }
+        // This consistently ~10 times faster than the equivalent regular
+        // expression irrespective of input length.
+        for (int i = 0; i < len; i++) {
+            char c = name.charAt(i);
+            if (c == '\"' || c == '<' || c == '>') {
+                // These characters are disallowed in Windows file names and
+                // there are known problems for file names with these characters
+                // when using File#getCanonicalPath().
+                // Note: There are additional characters that are disallowed in
+                //       Windows file names but these are not known to cause
+                //       problems when using File#getCanonicalPath().
+                return true;
+            }
+        }
+        // Windows does not allow file names to end in ' ' unless specific low
+        // level APIs are used to create the files that bypass various checks.
+        // File names that end in ' ' are known to cause problems when using
+        // File#getCanonicalPath().
+        if (name.charAt(len -1) == ' ') {
+            return true;
+        }
+        return false;
+    }
+
+
     /**
      * List the resources which are members of a collection.
      *

Copied: tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/JrePlatform.java (from r1809922, tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/compat/JrePlatform.java)
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/JrePlatform.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/JrePlatform.java&p1=tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/compat/JrePlatform.java&r1=1809922&r2=1809978&rev=1809978&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/compat/JrePlatform.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/naming/resources/JrePlatform.java Thu Sep 28 11:54:25 2017
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.tomcat.util.compat;
+package org.apache.naming.resources;
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;



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