From: Amos Jeffries Date: Fri, 8 Mar 2013 02:06:11 +0000 (-0700) Subject: Regression fix: Accept-Language header parse X-Git-Tag: SQUID_3_2_9~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db3c4d9d9ec66235545776627c3079d90174992d;p=thirdparty%2Fsquid.git Regression fix: Accept-Language header parse When handling error page negotiation the header parse to detect language code can enter into an infinite loop. Recover the 3.1 series behaviour and fix an additional pre-existing off-by-1 error. The errors were introduced in trunk rev.11496 in 3.2.0.9. --- diff --git a/src/errorpage.cc b/src/errorpage.cc index 68a0fb8977..9fdd6a7fec 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -376,17 +376,9 @@ bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &p while (pos < hdr.size()) { char *dt = lang; - if (!pos) { - /* skip any initial whitespace. */ - while (pos < hdr.size() && xisspace(hdr[pos])) - ++pos; - } else { - // IFF we terminated the tag on whitespace or ';' we need to skip to the next ',' or end of header. - while (pos < hdr.size() && hdr[pos] != ',') - ++pos; - if (hdr[pos] == ',') - ++pos; - } + /* skip any initial whitespace. */ + while (pos < hdr.size() && xisspace(hdr[pos])) + ++pos; /* * Header value format: @@ -417,6 +409,13 @@ bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &p *dt = '\0'; // nul-terminated the filename content string before system use. ++dt; + // if we terminated the tag on garbage or ';' we need to skip to the next ',' or end of header. + while (pos < hdr.size() && hdr[pos] != ',') + ++pos; + + if (pos < hdr.size() && hdr[pos] == ',') + ++pos; + debugs(4, 9, HERE << "STATE: dt='" << dt << "', lang='" << lang << "', pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'"); /* if we found anything we might use, try it. */ diff --git a/src/errorpage.h b/src/errorpage.h index d4104b061c..eac1f30eed 100644 --- a/src/errorpage.h +++ b/src/errorpage.h @@ -307,11 +307,16 @@ protected: /** * Parses the Accept-Language header value and return one language item on * each call. + * Will ignore any whitespace, q-values, and detectably invalid language + * codes in the header. + * * \param hdr is the Accept-Language header value - * \param lang a buffer given by the user to store parsed language + * \param lang a buffer to store parsed language code in * \param langlen the length of the lang buffer - * \param pos it is used to store the state of parsing. Must be "0" on first call - * \return true on success, false otherwise + * \param pos is used to store the offset state of parsing. Must be "0" on first call. + * Will be altered to point at the start of next field-value. + * \return true if something looking like a language token has been placed in lang, false otherwise */ bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos); + #endif /* SQUID_ERRORPAGE_H */