From: Martin Kraemer Date: Fri, 31 Aug 2007 09:29:18 +0000 (+0000) Subject: proxy/ajp_header.c: Fixed header token string comparisons X-Git-Tag: 2.2.6~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=746becff60cd8b776ed1bf4c79bdfe7e0ba68e0e;p=thirdparty%2Fapache%2Fhttpd.git proxy/ajp_header.c: Fixed header token string comparisons Matching of header tokens failed to include the trailing NIL byte and could misinterpret a longer header token for a shorter. Additionally, a "Content-Type" comparison was made case insensitive. Based on trunk rev. 571219,571232 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@571409 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index e962e641f01..831f8a41657 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.6 + *) proxy/ajp_header.c: Fixed header token string comparisons + Matching of header tokens failed to include the trailing NIL byte + and could misinterpret a longer header token for a shorter. + Additionally, a "Content-Type" comparison was made case insensitive. + [Martin Kraemer] + *) proxy/ajp_header.c: Backport of an AJP protocol fix for EBCDIC On EBCDIC machines, the status_line string was incorrectly converted twice. [Jean-Frederic Clere, Martin Kraemer] (based on rev. 357022) diff --git a/STATUS b/STATUS index 110acecc17f..89e785ba49d 100644 --- a/STATUS +++ b/STATUS @@ -195,37 +195,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: http://svn.apache.org/viewvc?view=rev&revision=429879 +1: niq, rpluem - * proxy/ajp_header.c: incorrect substring checks for header fields - The method of parsing the header line tokens is flakey: - it uses memcmp() to check, e.g., whether the header token is - "Accept-Charset:", by uppercasing the token name (-> "ACCEPT-CHARSET"), - then compares the initial "ACCEPT-" prefix, and then tests: - if (memcmp(p, "CHARSET", 7) == 0) return SC_ACCEPT_CHARSET; - but does not verify that the end of the token has been reached. - Thus, a header - Accept-CharsetXXX-Blah: utf-8 - would be mistaken for an "Accept-Charset: utf-8". - Same goes for a couple of other header names. - The patch replaces the memcmp by a strcmp to check for the trailing - NIL character, too. - Message-ID: <20070830105540.GA67279@deejai2.mch.fsc.net> - Trunk version of patch: - http://svn.apache.org/viewvc?rev=571219&view=rev - +1: jim, rpluem - +1: martin, with the exception of the "Content-Type" patch - which has been superseded with the patch following below - (http://svn.apache.org/viewvc?rev=571232&view=rev). - - * proxy/ajp_header.c: case sensitive comparison of literal "Content-Type" - IMO, and to be on the defensive side, I would replace - if (memcmp(stringname, "Content-Type", 12) == 0) { - by - if (strcasecmp(stringname, "Content-Type") == 0) { - as well. (that was not handled in the patch above) - Trunk version of patch: - http://svn.apache.org/viewvc?rev=571232&view=rev - +1: jim,martin,rpluem - PATCHES/ISSUES THAT ARE STALLED diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c index 11ef8896b47..07ffba97c07 100644 --- a/modules/proxy/ajp_header.c +++ b/modules/proxy/ajp_header.c @@ -51,7 +51,7 @@ static int sc_for_req_header(const char *header_name) const char *p = header_name; int i = 0; - /* ACCEPT-LANGUAGE is the longest headeer + /* ACCEPT-LANGUAGE is the longest header * that is of interest. */ if (len < 4 || len > 15) @@ -69,11 +69,11 @@ static int sc_for_req_header(const char *header_name) return SC_ACCEPT; else if (header[6] == '-') { p += 6; - if (memcmp(p, "CHARSET", 7) == 0) + if (strcmp(p, "CHARSET") == 0) return SC_ACCEPT_CHARSET; - else if (memcmp(p, "ENCODING", 8) == 0) + else if (strcmp(p, "ENCODING") == 0) return SC_ACCEPT_ENCODING; - else if (memcmp(p, "LANGUAGE", 8) == 0) + else if (strcmp(p, "LANGUAGE") == 0) return SC_ACCEPT_LANGUAGE; else return UNKNOWN_METHOD; @@ -81,45 +81,45 @@ static int sc_for_req_header(const char *header_name) else return UNKNOWN_METHOD; } - else if (memcmp(p, "UTHORIZATION", 12) == 0) + else if (strcmp(p, "UTHORIZATION") == 0) return SC_AUTHORIZATION; else return UNKNOWN_METHOD; break; case 'C': - if(memcmp(p, "OOKIE2", 6) == 0) + if(strcmp(p, "OOKIE2") == 0) return SC_COOKIE2; - else if (memcmp(p, "OOKIE", 5) == 0) + else if (strcmp(p, "OOKIE") == 0) return SC_COOKIE; - else if(memcmp(p, "ONNECTION", 9) == 0) + else if(strcmp(p, "ONNECTION") == 0) return SC_CONNECTION; - else if(memcmp(p, "ONTENT-TYPE", 11) == 0) + else if(strcmp(p, "ONTENT-TYPE") == 0) return SC_CONTENT_TYPE; - else if(memcmp(p, "ONTENT-LENGTH", 13) == 0) + else if(strcmp(p, "ONTENT-LENGTH") == 0) return SC_CONTENT_LENGTH; else return UNKNOWN_METHOD; break; case 'H': - if(memcmp(p, "OST", 3) == 0) + if(strcmp(p, "OST") == 0) return SC_HOST; else return UNKNOWN_METHOD; break; case 'P': - if(memcmp(p, "RAGMA", 5) == 0) + if(strcmp(p, "RAGMA") == 0) return SC_PRAGMA; else return UNKNOWN_METHOD; break; case 'R': - if(memcmp(p, "EFERER", 6) == 0) + if(strcmp(p, "EFERER") == 0) return SC_REFERER; else return UNKNOWN_METHOD; break; case 'U': - if(memcmp(p, "SER-AGENT", 9) == 0) + if(strcmp(p, "SER-AGENT") == 0) return SC_USER_AGENT; else return UNKNOWN_METHOD; @@ -562,7 +562,7 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg, apr_table_add(r->headers_out, stringname, value); /* Content-type needs an additional handling */ - if (memcmp(stringname, "Content-Type", 12) == 0) { + if (strcasecmp(stringname, "Content-Type") == 0) { /* add corresponding filter */ ap_set_content_type(r, apr_pstrdup(r->pool, value)); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,