From 3b10ce6318eed3b8ada254eca4040d24bb89dca8 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Sun, 23 Aug 2009 16:49:08 +1200 Subject: [PATCH] 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. --- src/HttpHeaderTools.cc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) 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); -- 2.47.2