This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new c484474  Relax parsing of 1#token to align with RFC 7230 section 7
c484474 is described below

commit c484474dc7a4fb6bc7fd7b2c6a797a1861e3122e
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Jun 16 09:45:31 2021 +0100

    Relax parsing of 1#token to align with RFC 7230 section 7
---
 .../apache/tomcat/util/http/parser/TokenList.java  | 41 ++++++++++++----------
 .../tomcat/util/http/parser/TestTokenList.java     |  6 ++--
 webapps/docs/changelog.xml                         |  5 +++
 3 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/java/org/apache/tomcat/util/http/parser/TokenList.java 
b/java/org/apache/tomcat/util/http/parser/TokenList.java
index 01ac449..ec69d3c 100644
--- a/java/org/apache/tomcat/util/http/parser/TokenList.java
+++ b/java/org/apache/tomcat/util/http/parser/TokenList.java
@@ -35,11 +35,12 @@ public class TokenList {
      * parsed values to lower case.
      *
      * @param inputs     The headers to parse
-     * @param collection The Collection (usually a list of a set) to which the
+     * @param collection The Collection (usually a list or a set) to which the
      *                       parsed tokens should be added
      *
-     * @return {@code} true if the header values were parsed cleanly, otherwise
-     *         {@code false} (e.g. if a non-token value was encountered)
+     * @return {@code} true if the header values were parsed cleanly and at
+     *         least one token was found, otherwise {@code false} (e.g. if a
+     *         non-token value was encountered)
      *
      * @throws IOException If an I/O error occurs reading the header
      */
@@ -59,14 +60,15 @@ public class TokenList {
 
     /**
      * Parses a header of the form 1#token, forcing all parsed values to lower
-     * case. This is typically used when header values are case-insensitive.
+     * case.
      *
      * @param input      The header to parse
-     * @param collection The Collection (usually a list of a set) to which the
+     * @param collection The Collection (usually a list or a set) to which the
      *                       parsed tokens should be added
      *
-     * @return {@code} true if the header was parsed cleanly, otherwise
-     *         {@code false} (e.g. if a non-token value was encountered)
+     * @return {@code} true if the header values were parsed cleanly and at
+     *         least one token was found, otherwise {@code false} (e.g. if a
+     *         non-token value was encountered)
      *
      * @throws IOException If an I/O error occurs reading the header
      */
@@ -75,17 +77,20 @@ public class TokenList {
         boolean valid = false;
 
         do {
-            String fieldName = HttpParser.readToken(input);
-            if (fieldName == null) {
-                // Invalid field-name, skip to the next one
-                invalid = true;
-                HttpParser.skipUntil(input, 0, ',');
+            String element = HttpParser.readToken(input);
+            if (element == null) {
+                // No token found. Could be empty element (which is OK for
+                // 1#token - see RFC 7230 section 7) or a non-token.
+                if (HttpParser.skipConstant(input, ",") != SkipResult.FOUND) {
+                    // Non-token element, skip to the next one
+                    invalid = true;
+                    HttpParser.skipUntil(input, 0, ',');
+                }
                 continue;
             }
 
-            if (fieldName.length() == 0) {
-                // Unexpected EOF. Should have been a token.
-                invalid = true;
+            if (element.length() == 0) {
+                // EOF after empty element
                 break;
             }
 
@@ -93,11 +98,11 @@ public class TokenList {
             if (skipResult == SkipResult.EOF) {
                 // EOF
                 valid = true;
-                collection.add(fieldName.toLowerCase(Locale.ENGLISH));
+                collection.add(element.toLowerCase(Locale.ENGLISH));
                 break;
             } else if (skipResult == SkipResult.FOUND) {
                 valid = true;
-                collection.add(fieldName.toLowerCase(Locale.ENGLISH));
+                collection.add(element.toLowerCase(Locale.ENGLISH));
                 continue;
             } else {
                 // Not a token - ignore it
@@ -108,7 +113,7 @@ public class TokenList {
         } while (true);
 
         // Only return true if at least one valid token was read and no invalid
-        // entries were found
+        // elements were found
         return valid && !invalid;
     }
 }
diff --git a/test/org/apache/tomcat/util/http/parser/TestTokenList.java 
b/test/org/apache/tomcat/util/http/parser/TestTokenList.java
index 99fcdb8..b520032 100644
--- a/test/org/apache/tomcat/util/http/parser/TestTokenList.java
+++ b/test/org/apache/tomcat/util/http/parser/TestTokenList.java
@@ -206,7 +206,7 @@ public class TestTokenList {
         expected.add("bar");
         expected.add("foo");
         expected.add("host");
-        doTestVary(",Host, Foo, Bar", expected, false);
+        doTestVary(",Host, Foo, Bar", expected, true);
     }
 
 
@@ -216,7 +216,7 @@ public class TestTokenList {
         expected.add("bar");
         expected.add("foo");
         expected.add("host");
-        doTestVary("Host, Foo,,Bar", expected, false);
+        doTestVary("Host, Foo,,Bar", expected, true);
     }
 
 
@@ -226,6 +226,6 @@ public class TestTokenList {
         expected.add("bar");
         expected.add("foo");
         expected.add("host");
-        doTestVary("Host, Foo, Bar,", expected, false);
+        doTestVary("Host, Foo, Bar,", expected, true);
     }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index dd1c057..31b4250 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -157,6 +157,11 @@
         <code>overheadCountFactor</code> providing for finer-grained control.
         (markt)
       </update>
+      <fix>
+        Modify the parsing of HTTP header values that use the
+        <code>1#token</code> to ignore empty elements as per RFC 7230 section 7
+        instead of treating the presence of empty elements as an error. (markt)
+      </fix>
     </changelog>
   </subsection>
 </section>

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

Reply via email to