]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Henrik Nordstrom <henrik@henriknordstrom.net>
authorAmos Jeffries <squid3@treenet.co.nz>
Sun, 23 Aug 2009 04:49:08 +0000 (16:49 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 23 Aug 2009 04:49:08 +0000 (16:49 +1200)
Bug 2541: Hang in 100% CPU loop while extacting header details using a delimiter other than comma

(external_acl_type, access_log_format, external_refresh_check)

strListGetItem() could get stuck in a 100% loop if called with a delimiter
other than ',' and the parsed string contains ','.

This change makes it properly detect ',' as a delimiter even if called
with another delimiter argument like intended. The reason why ',' is always
a delimiter is because this is the delimiter between merged values of a
multi-valued header, and must always be supported as delimiter even if
Cookie uses ';' instead.

src/HttpHeaderTools.cc

index 17ac5322942e58fb0dd381428b5d971aa44209e6..11ae11be2749190237b43c20702a647edc29c6af 100644 (file)
@@ -246,10 +246,16 @@ int
 strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos)
 {
     size_t len;
-    static char delim[3][8] = {
-                       "\"?,",
-                       "\"\\",
-                       " ?,\t\r\n"
+
+    /* ',' is always enabled as field delimiter as this is required for
+     * processing merged header values properly, even if Cookie normally
+     * uses ';' as delimiter.
+     */
+    static char delim[3][8] =
+    {
+       "\"?,",
+       "\"\\",
+       " ?,\t\r\n"
     };
     int quoted = 0;
     assert(str && item && pos);
@@ -264,7 +270,7 @@ strListGetItem(const String * str, char del, const char **item, int *ilen, const
             return 0;
     }
 
-    /* skip leading ws and delimiters */
+    /* skip leading whitespace and delimiters */
     *pos += strspn(*pos, delim[2]);
 
     *item = *pos;              /* remember item's start */
@@ -272,20 +278,15 @@ strListGetItem(const String * str, char del, const char **item, int *ilen, const
     /* find next delimiter */
     do {
         *pos += strcspn(*pos, delim[quoted]);
-
-        if (**pos == del)
-            break;
-
         if (**pos == '"') {
             quoted = !quoted;
             *pos += 1;
-        }
-
-        if (quoted && **pos == '\\') {
+       } else if (quoted && **pos == '\\') {
             *pos += 1;
-
             if (**pos)
                 *pos += 1;
+       } else {
+           break;              /* Delimiter found, marking the end of this value */
         }
     } while (**pos);