Author: markt Date: Sun Jun 3 20:04:08 2012 New Revision: 1345755 URL: http://svn.apache.org/viewvc?rev=1345755&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53353 Make the HTTP header parser for ContentType tolerant of invalid parameters with names but no values. The invalid parameters are available in the collection of output nodes but skipped by the various toString() methods.
Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1345752,1345754 Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java Sun Jun 3 20:04:08 2012 @@ -39,8 +39,12 @@ public class AstMediaType extends Simple sb.append('/'); sb.append(children[1].toString()); for (int i = 2; i < children.length; i++) { - sb.append(';'); - sb.append(children[i].toString()); + String s = children[i].toString(); + // Invalid parameters will have zero length - skip them + if (s.length() > 0) { + sb.append(';'); + sb.append(s); + } } return sb.toString(); } @@ -54,8 +58,12 @@ public class AstMediaType extends Simple AstParameter p = (AstParameter) children[i]; if (!CHARSET.equalsIgnoreCase( p.children[0].jjtGetValue().toString())) { - sb.append(';'); - sb.append(p.toString()); + String s = p.toString(); + // Invalid parameters will have zero length - skip them + if (s.length() > 0) { + sb.append(';'); + sb.append(p.toString()); + } } } return sb.toString(); Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java Sun Jun 3 20:04:08 2012 @@ -31,6 +31,10 @@ public class AstParameter extends Simple @Override public String toString() { + if (children.length != 2) { + // Invalid input - swallow it. + return ""; + } StringBuilder sb = new StringBuilder(); sb.append(children[0].toString()); sb.append("="); Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Sun Jun 3 20:04:08 2012 @@ -96,8 +96,15 @@ public class HttpParser/*@bgen(jjtree)*/ jjtree.openNodeScope(jjtn000); try { Attribute(); - jj_consume_token(EQUALS); - Value(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case EQUALS: + jj_consume_token(EQUALS); + Value(); + break; + default: + jj_la1[1] = jj_gen; + ; + } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); @@ -156,7 +163,7 @@ public class HttpParser/*@bgen(jjtree)*/ jjtn000.jjtSetValue(t.image.trim()); break; default: - jj_la1[1] = jj_gen; + jj_la1[2] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -176,13 +183,13 @@ public class HttpParser/*@bgen(jjtree)*/ public Token jj_nt; private int jj_ntk; private int jj_gen; - final private int[] jj_la1 = new int[2]; + final private int[] jj_la1 = new int[3]; static private int[] jj_la1_0; static { jj_la1_init_0(); } private static void jj_la1_init_0() { - jj_la1_0 = new int[] {0x2,0x180,}; + jj_la1_0 = new int[] {0x2,0x4,0x180,}; } /** Constructor with InputStream. */ @@ -196,7 +203,7 @@ public class HttpParser/*@bgen(jjtree)*/ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } /** Reinitialise. */ @@ -211,7 +218,7 @@ public class HttpParser/*@bgen(jjtree)*/ jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } /** Constructor. */ @@ -221,7 +228,7 @@ public class HttpParser/*@bgen(jjtree)*/ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } /** Reinitialise. */ @@ -232,7 +239,7 @@ public class HttpParser/*@bgen(jjtree)*/ jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } /** Constructor with generated Token Manager. */ @@ -241,7 +248,7 @@ public class HttpParser/*@bgen(jjtree)*/ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } /** Reinitialise. */ @@ -251,7 +258,7 @@ public class HttpParser/*@bgen(jjtree)*/ jj_ntk = -1; jjtree.reset(); jj_gen = 0; - for (int i = 0; i < 2; i++) jj_la1[i] = -1; + for (int i = 0; i < 3; i++) jj_la1[i] = -1; } private Token jj_consume_token(int kind) throws ParseException { @@ -307,7 +314,7 @@ public class HttpParser/*@bgen(jjtree)*/ la1tokens[jj_kind] = true; jj_kind = -1; } - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 3; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1<<j)) != 0) { Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt Sun Jun 3 20:04:08 2012 @@ -29,6 +29,10 @@ * * Provides parsing of the following HTTP header values as per RFC 2616: * - Content-Type + * Note: The parser tolerates invalid parameters that do not include a + * value. These parameters are available in the Parser node collection + * but will be skipped by the various toString() methods. See BZ 53353 + * for an example. * * Support for additional headers will be provided as required. */ @@ -77,7 +81,7 @@ void SubType() #SubType :{ Token t = nul void Parameter() #Parameter : {} { - Attribute() <EQUALS> Value() + Attribute() (<EQUALS> Value())? } void Attribute() # Attribute : { Token t = null; } Modified: tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java Sun Jun 3 20:04:08 2012 @@ -201,6 +201,41 @@ public class TestMediaType { } + @Test + public void testBug53353() throws ParseException { + String input = "text/html; UTF-8;charset=UTF-8"; + + StringReader sr = new StringReader(input); + HttpParser hp = new HttpParser(sr); + AstMediaType m = hp.MediaType(); + + assertTrue(m.children.length == 4); + + // Check the types + assertTrue(m.children[0] instanceof AstType); + assertTrue(m.children[1] instanceof AstSubType); + assertEquals("text", m.children[0].toString()); + assertEquals("html", m.children[1].toString()); + + // Check the parameters + AstParameter p = (AstParameter) m.children[2]; + assertTrue(p.children.length == 1); + assertTrue(p.children[0] instanceof AstAttribute); + assertEquals("UTF-8", p.children[0].toString()); + + p = (AstParameter) m.children[3]; + assertTrue(p.children.length == 2); + assertTrue(p.children[0] instanceof AstAttribute); + assertTrue(p.children[1] instanceof AstValue); + assertEquals("charset", p.children[0].toString()); + assertEquals("UTF-8", p.children[1].toString()); + + // Note: Invalid input is filtered out + assertEquals("text/html;charset=UTF-8", m.toString()); + assertEquals("UTF-8", m.getCharset()); + } + + private void doTest(Parameter... parameters) throws ParseException { StringBuilder sb = new StringBuilder(); sb.append(TYPES); Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1345755&r1=1345754&r2=1345755&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Sun Jun 3 20:04:08 2012 @@ -197,6 +197,11 @@ <bug>53342</bug>: To avoid BindException, make startStopThreads into a demon thread. (kfujino) </fix> + <fix> + <bug>53353</bug>: Make the internal HTTP header parser more tolerant of + Content-Type values that contain invalid parameters by ignoring the + invalid parameters. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org