From: Amos Jeffries Date: Sun, 23 Aug 2009 04:15:54 +0000 (+1200) Subject: Author: Henrik Nordstrom X-Git-Tag: SQUID_3_1_0_14~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=df0dfaa92d50d9b6c5db171ad724d0545e83d417;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 31d8359020..c598c61e4f 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -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);