Author: markt
Date: Sun Jun  3 19:55:33 2012
New Revision: 1345752

URL: http://svn.apache.org/viewvc?rev=1345752&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/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java
    tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java
    tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
    tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt
    tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java?rev=1345752&r1=1345751&r2=1345752&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java Sun 
Jun  3 19:55:33 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();
     }

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java?rev=1345752&r1=1345751&r2=1345752&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java Sun 
Jun  3 19:55:33 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/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=1345752&r1=1345751&r2=1345752&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 Sun 
Jun  3 19:55:33 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/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt?rev=1345752&r1=1345751&r2=1345752&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt Sun Jun 
 3 19:55:33 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/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=1345752&r1=1345751&r2=1345752&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 Sun 
Jun  3 19:55:33 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);



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to