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

Reply via email to