Description: Fixes CVE-2015-5174: Directory traversal vulnerability in RequestUtil
 allows remote authenticated users to bypass intended SecurityManager restrictions
 and list a parent directory via a /.. (slash dot dot) in a pathname used by a
 web application in a getResource, getResourceAsStream, or getResourcePaths call,
 as demonstrated by the $CATALINA_BASE/webapps directory.
Author: Markus Koschany <apo@debian.org>
Origin: backport, https://svn.apache.org/r1696281
                  https://svn.apache.org/r1700897
--- a/java/org/apache/tomcat/util/http/RequestUtil.java
+++ b/java/org/apache/tomcat/util/http/RequestUtil.java
@@ -56,9 +56,6 @@
         if (replaceBackSlash && normalized.indexOf('\\') >= 0)
             normalized = normalized.replace('\\', '/');
 
-        if (normalized.equals("/."))
-            return "/";
-
         // Add a leading "/" if necessary
         if (!normalized.startsWith("/"))
             normalized = "/" + normalized;
@@ -93,6 +90,14 @@
                 normalized.substring(index + 3);
         }
 
+        if (normalized.equals("/.")) {
+            return "/";
+        }
+
+        if (normalized.equals("/..")) {
+            return null;  // Trying to go outside our context
+        }
+
         // Return the normalized path that we have completed
         return (normalized);
     }
--- a/test/org/apache/tomcat/util/http/TestRequestUtil.java
+++ b/test/org/apache/tomcat/util/http/TestRequestUtil.java
@@ -23,11 +23,101 @@
 public class TestRequestUtil {
 
     @Test
-    public void testNormalizeString() {
-        assertEquals("/something",RequestUtil.normalize("//something"));
-        assertEquals("/some/thing",RequestUtil.normalize("some//thing"));
-        assertEquals("/something/",RequestUtil.normalize("something//"));
-        assertEquals("/",RequestUtil.normalize("//"));
+    public void testNormalize01() {
+        doTestNormalize("//something", "/something");
     }
 
+    @Test
+    public void testNormalize02() {
+        doTestNormalize("some//thing", "/some/thing");
+    }
+
+    @Test
+    public void testNormalize03() {
+        doTestNormalize("something//", "/something/");
+    }
+
+    @Test
+    public void testNormalize04() {
+        doTestNormalize("//", "/");
+    }
+
+        @Test
+    public void testNormalize05() {
+        doTestNormalize("//", "/");
+    }
+
+    @Test
+    public void testNormalize06() {
+        doTestNormalize("///", "/");
+    }
+
+    @Test
+    public void testNormalize07() {
+        doTestNormalize("////", "/");
+    }
+
+    @Test
+    public void testNormalize08() {
+        doTestNormalize("/.", "/");
+    }
+
+    @Test
+    public void testNormalize09() {
+        doTestNormalize("/./", "/");
+    }
+
+    @Test
+    public void testNormalize10() {
+        doTestNormalize(".", "/");
+    }
+
+    @Test
+    public void testNormalize11() {
+        doTestNormalize("/..", null);
+    }
+
+    @Test
+    public void testNormalize12() {
+        doTestNormalize("/../", null);
+    }
+
+    @Test
+    public void testNormalize13() {
+        doTestNormalize("..", null);
+    }
+
+    @Test
+    public void testNormalize14() {
+        doTestNormalize("//..", null);
+    }
+
+    @Test
+    public void testNormalize15() {
+        doTestNormalize("//../", null);
+    }
+
+    @Test
+    public void testNormalize16() {
+        doTestNormalize("/./..", null);
+    }
+
+    @Test
+    public void testNormalize17() {
+        doTestNormalize("/./../", null);
+    }
+
+    @Test
+    public void testNormalize18() {
+        doTestNormalize("/a/../..", null);
+    }
+
+    @Test
+    public void testNormalize19() {
+        doTestNormalize("/a/../../", null);
+    }
+
+    private void doTestNormalize(String input, String expected) {
+        assertEquals(expected,RequestUtil.normalize(input));
+    }
 }
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -1857,6 +1857,10 @@
         Enable non-blocking reads to take place on non-container threads.
         (markt)
       </fix>
+      <fix>
+        Correct a coupe of edge cases in <code>RequestUtil.normalize()</code>.
+        (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Cluster">
@@ -1868,6 +1872,13 @@
       </scode>
     </changelog>
   </subsection>
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Correct some edge cases in <code>RequestUtil.normalize()</code>. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Web applications">
     <changelog>
       <fix>
