Author: markt Date: Tue May 7 15:51:22 2013 New Revision: 1479951 URL: http://svn.apache.org/r1479951 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54703 Be tolerant of applications that pass CR or LF in setHeader() values. Fix some whitespace parsing issues idnetifed by the extended test cases in readTokenOrQuotedString()
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1479951&r1=1479950&r2=1479951&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Tue May 7 15:51:22 2013 @@ -260,17 +260,34 @@ public class HttpParser { } } - private static SkipConstantResult skipConstant(StringReader input, - String constant) throws IOException { - int len = constant.length(); + // Skip any LWS and return the next char + private static int skipLws(StringReader input, boolean withReset) + throws IOException { + if (withReset) { + input.mark(1); + } int c = input.read(); - // Skip lws - while (c == 32 || c == 9) { + while (c == 32 || c == 9 || c == 10 || c == 13) { + if (withReset) { + input.mark(1); + } c = input.read(); } + if (withReset) { + input.reset(); + } + return c; + } + + private static SkipConstantResult skipConstant(StringReader input, + String constant) throws IOException { + int len = constant.length(); + + int c = skipLws(input, false); + for (int i = 0; i < len; i++) { if (i == 0 && c == -1) { return SkipConstantResult.EOF; @@ -294,12 +311,7 @@ public class HttpParser { private static String readToken(StringReader input) throws IOException { StringBuilder result = new StringBuilder(); - int c = input.read(); - - // Skip lws - while (c == 32 || c == 9) { - c = input.read(); - } + int c = skipLws(input, false); while (c != -1 && isToken(c)) { result.append((char) c); @@ -323,12 +335,7 @@ public class HttpParser { private static String readQuotedString(StringReader input, boolean returnQuoted) throws IOException { - int c = input.read(); - - // Skip lws - while (c == 32 || c == 9) { - c = input.read(); - } + int c = skipLws(input, false); if (c != '"') { return null; @@ -364,12 +371,8 @@ public class HttpParser { private static String readTokenOrQuotedString(StringReader input, boolean returnQuoted) throws IOException { - // Use mark/reset as skip(-1) fails when reading the last character of - // the input - input.mark(1); - int c = input.read(); - // Go back so first character is available to be read again - input.reset(); + // Go back so first non-LWS character is available to be read again + int c = skipLws(input, true); if (c == '"') { return readQuotedString(input, returnQuoted); @@ -396,12 +399,7 @@ public class HttpParser { StringBuilder result = new StringBuilder(); boolean quoted = false; - int c = input.read(); - - // Skip lws - while (c == 32 || c == 9) { - c = input.read(); - } + int c = skipLws(input, false); if (c == '"') { quoted = true; @@ -453,12 +451,7 @@ public class HttpParser { StringBuilder result = new StringBuilder(); boolean quoted = false; - int c = input.read(); - - // Skip lws - while (c == 32 || c == 9) { - c = input.read(); - } + int c = skipLws(input, false); if (c == '"') { quoted = true; Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java?rev=1479951&r1=1479950&r2=1479951&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java Tue May 7 15:51:22 2013 @@ -46,6 +46,7 @@ public class TestMediaType { new Parameter("z", "\"\""); private static final Parameter PARAM_COMPLEX_QUOTED = new Parameter("w", "\"foo'bar,a=b;x=y\""); + private static final String CHARSET = "UTF-8"; private static final String WS_CHARSET = " \tUTF-8"; private static final String CHARSET_WS = "UTF-8 \t"; @@ -61,6 +62,11 @@ public class TestMediaType { new Parameter("charset", CHARSET_QUOTED); + private static final String[] LWS_VALUES = new String[] { + "", " ", "\t", "\r", "\n", "\r\n", " \r", " \n", " \r\n", + "\r ", "\n ", "\r\n ", " \r ", " \n ", " \r\n " }; + + @Test public void testSimple() throws IOException { doTest(); @@ -207,10 +213,17 @@ public class TestMediaType { private void doTest(Parameter... parameters) throws IOException { + for (String lws : LWS_VALUES) { + doTest(lws, parameters); + } + } + + private void doTest(String lws, Parameter... parameters) + throws IOException { StringBuilder sb = new StringBuilder(); sb.append(TYPES); for (Parameter p : parameters) { - sb.append(p.toString()); + sb.append(p.toString(lws)); } StringReader sr = new StringReader(sb.toString()); @@ -250,14 +263,23 @@ public class TestMediaType { @Override public String toString() { + return toString(""); + } + + public String toString(String lws) { StringBuilder sb = new StringBuilder(); + sb.append(lws); sb.append(";"); + sb.append(lws); sb.append(name); + sb.append(lws); sb.append("="); + sb.append(lws); sb.append(value); + sb.append(lws); return sb.toString(); } - } +} @Test public void testCase() throws Exception { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org