Author: markt Date: Wed Jul 11 08:26:26 2012 New Revision: 1360059 URL: http://svn.apache.org/viewvc?rev=1360059&view=rev Log: Handle fragments as well as query strings in normalisation of redirects
Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java tomcat/trunk/test/org/apache/catalina/connector/TestResponse.java Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1360059&r1=1360058&r2=1360059&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Wed Jul 11 08:26:26 2012 @@ -27,6 +27,7 @@ import java.security.PrivilegedActionExc import java.security.PrivilegedExceptionAction; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.List; @@ -1654,16 +1655,17 @@ public class Response * Code borrowed heavily from CoyoteAdapter.normalize() */ private void normalize(CharChunk cc) { - // Strip query string first (doing it this way makes the logic a lot - // simpler) - int query = cc.indexOf('?'); - char[] queryCC = null; - if (query > -1) { - queryCC = new char[cc.getEnd() - query]; - for (int i = query; i < cc.getEnd(); i++) { - queryCC[i - query] = cc.charAt(i); - } - cc.setEnd(query); + // Strip query string and/or fragment first as doing it this way makes + // the normalization logic a lot simpler + int truncate = cc.indexOf('?'); + if (truncate == -1) { + truncate = cc.indexOf('#'); + } + char[] truncateCC = null; + if (truncate > -1) { + truncateCC = Arrays.copyOfRange(cc.getBuffer(), + cc.getStart() + truncate, cc.getEnd()); + cc.setEnd(cc.getStart() + truncate); } if (cc.endsWith("/.") || cc.endsWith("/..")) { @@ -1726,9 +1728,9 @@ public class Response } // Add the query string (if present) back in - if (queryCC != null) { + if (truncateCC != null) { try { - cc.append(queryCC, 0, queryCC.length); + cc.append(truncateCC, 0, truncateCC.length); } catch (IOException ioe) { throw new IllegalArgumentException(ioe); } Modified: tomcat/trunk/test/org/apache/catalina/connector/TestResponse.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestResponse.java?rev=1360059&r1=1360058&r2=1360059&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/connector/TestResponse.java (original) +++ tomcat/trunk/test/org/apache/catalina/connector/TestResponse.java Wed Jul 11 08:26:26 2012 @@ -271,8 +271,7 @@ public class TestResponse extends Tomcat String result = resp.toAbsolute("./.?x=/../../"); Assert.assertEquals( - "http://localhost:8080/level1/level2/?x=/../../", - result); + "http://localhost:8080/level1/level2/?x=/../../", result); } @@ -284,9 +283,7 @@ public class TestResponse extends Tomcat String result = resp.toAbsolute("./..?x=/../../"); - Assert.assertEquals( - "http://localhost:8080/level1/?x=/../../", - result); + Assert.assertEquals("http://localhost:8080/level1/?x=/../../", result); } @@ -304,6 +301,69 @@ public class TestResponse extends Tomcat } + @Test + public void testBug53062l() throws Exception { + Request req = new TesterMockRequest(); + Response resp = new Response(); + resp.setRequest(req); + + String result = resp.toAbsolute("bar.html#/../"); + + Assert.assertEquals( + "http://localhost:8080/level1/level2/bar.html#/../", result); + } + + + @Test + public void testBug53062m() throws Exception { + Request req = new TesterMockRequest(); + Response resp = new Response(); + resp.setRequest(req); + + String result = resp.toAbsolute("bar.html#/../../"); + + Assert.assertEquals( + "http://localhost:8080/level1/level2/bar.html#/../../", result); + } + + + @Test + public void testBug53062n() throws Exception { + Request req = new TesterMockRequest(); + Response resp = new Response(); + resp.setRequest(req); + + String result = resp.toAbsolute("./.#/../../"); + + Assert.assertEquals( + "http://localhost:8080/level1/level2/#/../../", result); + } + + + @Test + public void testBug53062o() throws Exception { + Request req = new TesterMockRequest(); + Response resp = new Response(); + resp.setRequest(req); + + String result = resp.toAbsolute("./..#/../../"); + + Assert.assertEquals("http://localhost:8080/level1/#/../../", result); + } + + + @Test + public void testBug53062p() throws Exception { + Request req = new TesterMockRequest(); + Response resp = new Response(); + resp.setRequest(req); + + String result = resp.toAbsolute("./..#/../.."); + + Assert.assertEquals("http://localhost:8080/level1/#/../..", result); + } + + private static final class Bug52811Servlet extends HttpServlet { private static final long serialVersionUID = 1L; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org