From: Amos Jeffries Date: Sat, 8 Feb 2014 16:07:01 +0000 (-0800) Subject: Upgrade HTPT header parser getStringPrefix() X-Git-Tag: merge-candidate-3-v1~506^2~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81858ebcb6f21ad67fd4766ab94c564853cebf09;p=thirdparty%2Fsquid.git Upgrade HTPT header parser getStringPrefix() ... to use string length instead of start-end char* pointers. --- diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 9291036afb..f84a017290 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -555,13 +555,13 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) PROF_start(HttpHeaderParse); assert(header_start && header_end); - debugs(55, 7, "parsing hdr: (" << this << ")" << std::endl << getStringPrefix(header_start, header_end)); + debugs(55, 7, "parsing hdr: (" << this << ")" << std::endl << getStringPrefix(header_start, hdrLen)); ++ HttpHeaderStats[owner].parsedCount; char *nulpos; if ((nulpos = (char*)memchr(header_start, '\0', hdrLen))) { debugs(55, DBG_IMPORTANT, "WARNING: HTTP header contains NULL characters {" << - getStringPrefix(header_start, nulpos) << "}\nNULL\n{" << getStringPrefix(nulpos+1, header_end)); + getStringPrefix(header_start, nulpos-header_start) << "}\nNULL\n{" << getStringPrefix(nulpos+1, hdrLen-(nulpos-header_start)-1)); PROF_stop(HttpHeaderParse); return reset(); } @@ -598,7 +598,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if (cr_only) { debugs(55, DBG_IMPORTANT, "SECURITY WARNING: Rejecting HTTP request with a CR+ " "header field to prevent request smuggling attacks: {" << - getStringPrefix(header_start, header_end) << "}"); + getStringPrefix(header_start, hdrLen) << "}"); PROF_stop(HttpHeaderParse); return reset(); } @@ -608,7 +608,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) /* Barf on stray CR characters */ if (memchr(this_line, '\r', field_end - this_line)) { debugs(55, warnOnError, "WARNING: suspicious CR characters in HTTP header {" << - getStringPrefix(field_start, field_end) << "}"); + getStringPrefix(field_start, field_end-field_start) << "}"); if (Config.onoff.relaxed_header_parser) { char *p = (char *) this_line; /* XXX Warning! This destroys original header content and violates specifications somewhat */ @@ -625,7 +625,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if (this_line + 1 == field_end && this_line > field_start) { debugs(55, warnOnError, "WARNING: Blank continuation line in HTTP header {" << - getStringPrefix(header_start, header_end) << "}"); + getStringPrefix(header_start, hdrLen) << "}"); PROF_stop(HttpHeaderParse); return reset(); } @@ -634,7 +634,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if (field_start == field_end) { if (field_ptr < header_end) { debugs(55, warnOnError, "WARNING: unparseable HTTP header field near {" << - getStringPrefix(field_start, header_end) << "}"); + getStringPrefix(field_start, hdrLen-(field_start-header_start)) << "}"); PROF_stop(HttpHeaderParse); return reset(); } @@ -644,8 +644,8 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if ((e = HttpHeaderEntry::parse(field_start, field_end)) == NULL) { debugs(55, warnOnError, "WARNING: unparseable HTTP header field {" << - getStringPrefix(field_start, field_end) << "}"); - debugs(55, warnOnError, " in {" << getStringPrefix(header_start, header_end) << "}"); + getStringPrefix(field_start, field_end-field_start) << "}"); + debugs(55, warnOnError, " in {" << getStringPrefix(header_start, hdrLen) << "}"); if (Config.onoff.relaxed_header_parser) continue; @@ -658,7 +658,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if (e->value != e2->value) { int64_t l1, l2; debugs(55, warnOnError, "WARNING: found two conflicting content-length headers in {" << - getStringPrefix(header_start, header_end) << "}"); + getStringPrefix(header_start, hdrLen) << "}"); if (!Config.onoff.relaxed_header_parser) { delete e; @@ -693,7 +693,7 @@ HttpHeader::parse(const char *header_start, size_t hdrLen) if (e->id == HDR_OTHER && stringHasWhitespace(e->name.termedBuf())) { debugs(55, warnOnError, "WARNING: found whitespace in HTTP header name {" << - getStringPrefix(field_start, field_end) << "}"); + getStringPrefix(field_start, field_end-field_start) << "}"); if (!Config.onoff.relaxed_header_parser) { delete e; @@ -1579,7 +1579,7 @@ HttpHeaderEntry::parse(const char *field_start, const char *field_end) if (Config.onoff.relaxed_header_parser && xisspace(field_start[name_len - 1])) { debugs(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2, - "NOTICE: Whitespace after header name in '" << getStringPrefix(field_start, field_end) << "'"); + "NOTICE: Whitespace after header name in '" << getStringPrefix(field_start, field_end-field_start) << "'"); while (name_len > 0 && xisspace(field_start[name_len - 1])) --name_len; @@ -1590,7 +1590,7 @@ HttpHeaderEntry::parse(const char *field_start, const char *field_end) /* now we know we can parse it */ - debugs(55, 9, "parsing HttpHeaderEntry: near '" << getStringPrefix(field_start, field_end) << "'"); + debugs(55, 9, "parsing HttpHeaderEntry: near '" << getStringPrefix(field_start, field_end-field_start) << "'"); /* is it a "known" field? */ http_hdr_type id = httpHeaderIdByName(field_start, name_len, Headers, HDR_ENUM_END); diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 0f6a264607..cba504c990 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -185,12 +185,11 @@ httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive) /** handy to printf prefixes of potentially very long buffers */ const char * -getStringPrefix(const char *str, const char *end) +getStringPrefix(const char *str, size_t sz) { #define SHORT_PREFIX_SIZE 512 LOCAL_ARRAY(char, buf, SHORT_PREFIX_SIZE); - const int sz = 1 + (end ? end - str : strlen(str)); - xstrncpy(buf, str, (sz > SHORT_PREFIX_SIZE) ? SHORT_PREFIX_SIZE : sz); + xstrncpy(buf, str, (sz+1 > SHORT_PREFIX_SIZE) ? SHORT_PREFIX_SIZE : sz); return buf; } diff --git a/src/HttpHeaderTools.h b/src/HttpHeaderTools.h index ac273b3494..dbab99862b 100644 --- a/src/HttpHeaderTools.h +++ b/src/HttpHeaderTools.h @@ -124,7 +124,7 @@ int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); int httpHeaderParseInt(const char *start, int *val); void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...) PRINTF_FORMAT_ARG3; -const char *getStringPrefix(const char *str, const char *end); +const char *getStringPrefix(const char *str, size_t len); void httpHdrMangleList(HttpHeader *, HttpRequest *, int req_or_rep);