From: Amos Jeffries Date: Sun, 23 Aug 2009 04:49:08 +0000 (+1200) Subject: Author: Henrik Nordstrom X-Git-Tag: SQUID_3_0_STABLE19~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b10ce6318eed3b8ada254eca4040d24bb89dca8;p=thirdparty%2Fsquid.git Author: Henrik Nordstrom 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. --- diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 17ac532294..11ae11be27 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -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);