You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/11/03 16:26:21 UTC

svn commit: r1405357 - in /tomcat/trunk: java/org/apache/catalina/authenticator/DigestAuthenticator.java java/org/apache/tomcat/util/http/parser/HttpParser2.java test/org/apache/tomcat/util/http/parser/TestHttpParser2.java

Author: markt
Date: Sat Nov  3 15:26:21 2012
New Revision: 1405357

URL: http://svn.apache.org/viewvc?rev=1405357&view=rev
Log:
Refactor HttpParser2 not to throw exceptions on invalid input

Modified:
    tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
    tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
    tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParser2.java

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1405357&r1=1405356&r2=1405357&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Sat Nov  3 15:26:21 2012
@@ -481,7 +481,11 @@ public class DigestAuthenticator extends
             try {
                 directives = HttpParser2.parseAuthorizationDigest(
                         new StringReader(authorization));
-            } catch (IllegalArgumentException | IOException e) {
+            } catch (IOException e) {
+                return false;
+            }
+
+            if (directives == null) {
                 return false;
             }
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java?rev=1405357&r1=1405356&r2=1405357&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java Sat Nov  3 15:26:21 2012
@@ -98,7 +98,8 @@ public class HttpParser2 {
      *
      * @param input The header value to parse
      *
-     * @return  A map of directives and values as {@link String}s. Although the
+     * @return  A map of directives and values as {@link String}s or
+     *          <code>null</code> if a parsing error occurs. Although the
      *          values returned are {@link String}s they will have been
      *          validated to ensure that they conform to RFC 2617.
      *
@@ -111,13 +112,20 @@ public class HttpParser2 {
 
         Map<String,String> result = new HashMap<>();
 
-        swallowConstant(input, "Digest", false);
+        if (!skipConstant(input, "Digest", false)) {
+            return null;
+        }
         skipLws(input);
         // All field names are valid tokens
         String field = readToken(input);
-        while (field != null) {
+        if (field == null) {
+            return null;
+        }
+        while (!field.equals("")) {
             skipLws(input);
-            swallowConstant(input, "=", false);
+            if (!skipConstant(input, "=", false)) {
+                return null;
+            }
             skipLws(input);
             String value = null;
             Integer type = fieldTypes.get(field.toLowerCase(Locale.US));
@@ -152,34 +160,40 @@ public class HttpParser2 {
                             "TODO i18n: Unsupported type");
             }
 
+            if (value == null) {
+                return null;
+            }
             result.put(field, value);
 
             skipLws(input);
-            if (!swallowConstant(input, ",", true)) {
-                break;
+            if (!skipConstant(input, ",", true)) {
+                return null;
             }
             skipLws(input);
             field = readToken(input);
+            if (field == null) {
+                return null;
+            }
         }
 
         return result;
     }
 
-    private static boolean swallowConstant(StringReader input, String constant,
-            boolean optional) throws IOException {
+    /**
+     * @return  <code>true</code> if the constant is found or if no data is
+     *          present and EOF is allowed otherwise returns <code>false</code>
+     */
+    private static boolean skipConstant(StringReader input, String constant,
+            boolean eofOk) throws IOException {
         int len = constant.length();
 
         for (int i = 0; i < len; i++) {
             int c = input.read();
+            if (i == 0 && c == -1 && eofOk) {
+                return true;
+            }
             if (c != constant.charAt(i)) {
-                if (optional) {
-                    input.skip(-(i+1));
-                    return false;
-                } else {
-                    throw new IllegalArgumentException(
-                            "TODO I18N: Failed to parse input for [" + constant +
-                            "]");
-                }
+                return false;
             }
         }
         return true;
@@ -195,6 +209,11 @@ public class HttpParser2 {
         input.skip(-1);
     }
 
+    /**
+     * @return  the token if one was found, the empty string if no data was
+     *          available to read or <code>null</code> if data other than a
+     *          token was found
+     */
     private static String readToken(StringReader input) throws IOException {
         StringBuilder result = new StringBuilder();
 
@@ -206,16 +225,24 @@ public class HttpParser2 {
         // Skip back so non-token character is available for next read
         input.skip(-1);
 
-        return result.toString();
+        if (c != -1 && result.length() == 0) {
+            return null;
+        } else {
+            return result.toString();
+        }
     }
 
+    /**
+     * @return the quoted string if one was found, null if data other than a
+     *         quoted string was found or null if the end of data was reached
+     *         before the quoted string was terminated
+     */
     private static String readQuotedString(StringReader input)
             throws IOException {
 
         int c = input.read();
         if (c != '"') {
-            throw new IllegalArgumentException(
-                    "TODO i18n: Quoted string must start with a quote");
+            return null;
         }
 
         StringBuilder result = new StringBuilder();
@@ -223,8 +250,7 @@ public class HttpParser2 {
         c = input.read();
         while (c != '"') {
             if (c == -1) {
-                throw new IllegalArgumentException(
-                        "TODO i18n: Quoted string must end with a quote");
+                return null;
             } else if (c == '\\') {
                 c = input.read();
                 result.append(c);
@@ -249,9 +275,12 @@ public class HttpParser2 {
         }
     }
 
-    /*
+    /**
      * Parses lower case hex but permits upper case hex to be used (converting
      * it to lower case before returning).
+     *
+     * @return the lower case hex if present or <code>null</code> if data other
+     *         than lower case hex was found
      */
     private static String readLhex(StringReader input) throws IOException {
         StringBuilder result = new StringBuilder();
@@ -264,15 +293,19 @@ public class HttpParser2 {
         // Skip back so non-hex character is available for next read
         input.skip(-1);
 
-        return result.toString().toLowerCase();
+        if (result.length() == 0) {
+            return null;
+        } else {
+            return result.toString().toLowerCase();
+        }
     }
 
     private static String readQuotedLhex(StringReader input)
             throws IOException {
 
-        swallowConstant(input, "\"", false);
+        skipConstant(input, "\"", false);
         String result = readLhex(input);
-        swallowConstant(input, "\"", false);
+        skipConstant(input, "\"", false);
 
         return result;
     }

Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParser2.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParser2.java?rev=1405357&r1=1405356&r2=1405357&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParser2.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParser2.java Sat Nov  3 15:26:21 2012
@@ -125,31 +125,34 @@ public class TestHttpParser2 {
         Assert.assertEquals("00000001", result.get("nc"));
     }
 
-    @Test(expected=IllegalArgumentException.class)
+    @Test
     public void testUnclosedQuotedString1() throws Exception {
         String header = "Digest username=\"test";
 
         StringReader input = new StringReader(header);
 
-        HttpParser2.parseAuthorizationDigest(input);
+        Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+        Assert.assertNull(result);
     }
 
-    @Test(expected=IllegalArgumentException.class)
+    @Test
     public void testUnclosedQuotedString2() throws Exception {
         String header = "Digest username=\"test\\";
 
         StringReader input = new StringReader(header);
 
-        HttpParser2.parseAuthorizationDigest(input);
+        Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+        Assert.assertNull(result);
     }
 
-    @Test(expected=IllegalArgumentException.class)
+    @Test
     public void testNonTokenDirective() throws Exception {
         String header = "Digest user{name=\"test\"";
 
         StringReader input = new StringReader(header);
 
-        HttpParser2.parseAuthorizationDigest(input);
+        Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+        Assert.assertNull(result);
     }
 
 }



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