Author: markt
Date: Wed Jan  8 14:15:57 2014
New Revision: 1556540

URL: http://svn.apache.org/r1556540
Log:
Add support for limiting the size of chunk extensions when using chunked 
encoding.

Modified:
    tomcat/tc6.0.x/trunk/STATUS.txt
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/Constants.java
    
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc6.0.x/trunk/webapps/docs/config/systemprops.xml

Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1556540&r1=1556539&r2=1556540&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Wed Jan  8 14:15:57 2014
@@ -32,12 +32,6 @@ PATCHES PROPOSED TO BACKPORT:
   [ New proposals should be added at the end of the list ]
 
 
-* Add support for limiting the size of chunk extensions when using chunked
-  encoding.
-  
http://people.apache.org/~markt/patches/2013-12-17-chunk-extensions-tc6-v2.patch
-  +1: markt, kkolinko, remm, jboynes
-  -1:
-
 * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55749
   Improve the error message when SSLEngine is disabled in AprLifecycleListener
   and SSL is configured for an APR/native connector.

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/Constants.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/Constants.java?rev=1556540&r1=1556539&r2=1556540&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/Constants.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/Constants.java Wed Jan  8 
14:15:57 2014
@@ -76,4 +76,13 @@ public final class Constants {
         Integer.parseInt(System.getProperty(
                 "org.apache.coyote.MAX_TRAILER_SIZE",
                 "8192"));
+
+    /**
+     * Limit on the total length of the extension data in
+     * a chunked HTTP request.
+     */
+    public static final int MAX_EXTENSION_SIZE =
+        Integer.parseInt(System.getProperty(
+                "org.apache.coyote.MAX_EXTENSION_SIZE",
+                "8192"));
 }

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java?rev=1556540&r1=1556539&r2=1556540&view=diff
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
 (original)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
 Wed Jan  8 14:15:57 2014
@@ -114,6 +114,12 @@ public class ChunkedInputFilter implemen
 
 
     /**
+     * Size of extensions processed for this request.
+     */
+    private long extensionSize;
+    
+    
+    /**
      * Flag set to true if the next call to doRead() must parse a CRLF pair
      * before doing anything else.
      */
@@ -248,6 +254,10 @@ public class ChunkedInputFilter implemen
         endChunk = false;
         needCRLFParse = false;
         trailingHeaders.recycle();
+        if (org.apache.coyote.Constants.MAX_TRAILER_SIZE > 0) {
+            
trailingHeaders.setLimit(org.apache.coyote.Constants.MAX_TRAILER_SIZE);
+        }
+        extensionSize = 0;
     }
 
 
@@ -294,7 +304,7 @@ public class ChunkedInputFilter implemen
         int result = 0;
         boolean eol = false;
         boolean readDigit = false;
-        boolean trailer = false;
+        boolean extension = false;
 
         while (!eol) {
 
@@ -306,9 +316,13 @@ public class ChunkedInputFilter implemen
             if (buf[pos] == Constants.CR || buf[pos] == Constants.LF) {
                 parseCRLF(false);
                 eol = true;
-            } else if (buf[pos] == Constants.SEMI_COLON) {
-                trailer = true;
-            } else if (!trailer) { 
+            } else if (buf[pos] == Constants.SEMI_COLON && !extension) {
+                // First semi-colon marks the start of the extension. Further
+                // semi-colons may appear to separate multiple 
chunk-extensions.
+                // These need to be processed as part of parsing the 
extensions.
+                extension = true;
+                extensionSize++;
+            } else if (!extension) { 
                 //don't read data after the trailer
                 int charValue = HexUtils.getDec(buf[pos]);
                 if (charValue != -1) {
@@ -320,6 +334,15 @@ public class ChunkedInputFilter implemen
                     //in the chunked header
                     return false;
                 }
+            } else {
+                // Extension 'parsing'
+                // Note that the chunk-extension is neither parsed nor
+                // validated. Currently it is simply ignored.
+                extensionSize++;
+                if (org.apache.coyote.Constants.MAX_EXTENSION_SIZE > -1 &&
+                        extensionSize > 
org.apache.coyote.Constants.MAX_EXTENSION_SIZE) {
+                    throw new IOException("maxExtensionSize exceeded");
+                }
             }
 
             // Parsing the CRLF increments pos
@@ -485,6 +508,15 @@ public class ChunkedInputFilter implemen
                 chr = buf[pos];
                 if ((chr == Constants.SP) || (chr == Constants.HT)) {
                     pos++;
+                    // If we swallow whitespace, make sure it counts towards 
the
+                    // limit placed on trailing header size (if there is one)
+                    if (trailingHeaders.getLimit() != -1) {
+                        int newlimit = trailingHeaders.getLimit() -1;
+                        if (trailingHeaders.getEnd() > newlimit) {
+                            throw new IOException("Exceeded maxTrailerSize");
+                        }
+                        trailingHeaders.setLimit(newlimit);
+                    }
                 } else {
                     space = false;
                 }

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1556540&r1=1556539&r2=1556540&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Wed Jan  8 14:15:57 2014
@@ -108,6 +108,10 @@
       <fix>
         Better adherence to RFC2616 for content-length headers. (markt)
       </fix>
+      <fix>
+        Add support for limiting the size of chunk extensions when using 
chunked
+        encoding. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">

Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/systemprops.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/systemprops.xml?rev=1556540&r1=1556539&r2=1556540&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/config/systemprops.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/config/systemprops.xml Wed Jan  8 
14:15:57 2014
@@ -420,6 +420,13 @@
 
   <properties>
 
+    <property name="org.apache.coyote.MAX_EXTENSION_SIZE">
+      <p>Limits the total length of extension data when using chunked encoding.
+      If the value is <code>-1</code>, no limit will be imposed.</p>
+      <p>If not specified, the default value of <code>8192</code> will be
+      used.</p>
+    </property>
+
     <property name="org.apache.coyote.MAX_TRAILER_SIZE">
       <p>Limits the total length of trailing headers in the last chunk of
       a chunked HTTP request.



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

Reply via email to