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: [email protected]
For additional commands, e-mail: [email protected]