]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #2541: Hang in 100% CPU loop while extacting header details using a delimiter...
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 20 Aug 2009 12:13:35 +0000 (14:13 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 20 Aug 2009 12:13:35 +0000 (14:13 +0200)
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 31d83590206393050c1a06619255778a87a87ba9..c598c61e4f927cc78cf7c13e727dd37fba347def 100644 (file)
@@ -229,7 +229,12 @@ int
 strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos)
 {
     size_t len;
-    static char delim[3][8] = {
+    /* ',' 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"
@@ -247,7 +252,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 */
@@ -255,20 +260,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);