diff --git a/lib/http.c b/lib/http.c index 6fdaa2e434..487973e06c 100644 --- a/lib/http.c +++ b/lib/http.c @@ -175,7 +175,7 @@ static bool header_has_value(const char **headerp, struct Curl_str *outp) (!curlx_str_single(headerp, ':') || !curlx_str_single(headerp, ';')); if(value) { - curlx_str_untilnl(headerp, outp, MAX_HTTP_RESP_HEADER_SIZE); + curlx_str_cspn(headerp, outp, "\r\n"); curlx_str_trimblanks(outp); } return value; @@ -1415,7 +1415,7 @@ bool Curl_compareheader(const char *headerline, /* line to check */ /* pass the header */ p = &headerline[hlen]; - if(curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE)) + if(curlx_str_cspn(&p, &val, "\r\n")) return FALSE; curlx_str_trimblanks(&val); @@ -1432,7 +1432,7 @@ bool Curl_compareheader(const char *headerline, /* line to check */ !p[clen])) return TRUE; /* match! */ /* advance to the next comma */ - if(curlx_str_until(&p, &next, MAX_HTTP_RESP_HEADER_SIZE, ',') || + if(curlx_str_until(&p, &next, len, ',') || curlx_str_single(&p, ',')) break; /* no comma, get out */ @@ -1784,21 +1784,22 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, struct Curl_str name; const char *p = headers->data; const char *origp = p; + size_t hlen = strlen(origp); /* explicitly asked to send header without content is done by a header that ends with a semicolon, but there must be no colon present in the name */ - if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ';') && + if(!curlx_str_until(&p, &name, hlen, ';') && !curlx_str_single(&p, ';') && !curlx_str_single(&p, '\0') && !memchr(curlx_str(&name), ':', curlx_strlen(&name))) blankheader = TRUE; else { p = origp; - if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ':') && + if(!curlx_str_until(&p, &name, hlen, ':') && !curlx_str_single(&p, ':')) { struct Curl_str val; - curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE); + curlx_str_untilnl(&p, &val, hlen); curlx_str_trimblanks(&val); if(!curlx_strlen(&val)) /* no content, do not send this */ @@ -1849,9 +1850,11 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, other hosts */ !Curl_auth_allowed_to_host(data)) ; - else if(blankheader) - result = curlx_dyn_addf(req, "%.*s:\r\n", (int)curlx_strlen(&name), - curlx_str(&name)); + else if(blankheader) { + result = curlx_dyn_addn(req, curlx_str(&name), curlx_strlen(&name)); + if(!result) + result = curlx_dyn_addn(req, STRCONST(":\r\n")); + } else result = curlx_dyn_addf(req, "%s\r\n", origp); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 32ad4b1e52..760a37a05f 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -284,7 +284,7 @@ test3100 test3101 test3102 test3103 test3104 test3105 test3106 \ test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 \ test3208 test3209 test3210 test3211 test3212 test3213 test3214 test3215 \ test3216 test3217 test3218 test3219 test3220 test3221 test3222 \ -test3223 test3224 test3225 test3226 test3227 \ +test3223 test3224 test3225 test3226 test3227 test3228 test3229 \ \ test3300 test3301 test3302 test3303 test3304 test3305 \ \ diff --git a/tests/data/test3228 b/tests/data/test3228 new file mode 100644 index 0000000000..c0ad8ab5eb --- /dev/null +++ b/tests/data/test3228 @@ -0,0 +1,58 @@ + + + + +HTTP +HTTP GET +HTTP added headers + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 6 +Connection: close + +-foo- + + + +# Client-side + + +http + + +Send custom request headers larger than the response header limit + + +header "X-Large: %repeat[307200 x x]%" +header "Connection: %repeat[307200 x x]%" +header "%repeat[307201 x X]%;" + + +-K - http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +X-Large: %repeat[307200 x x]% +%repeat[307201 x X]%: +Connection: %repeat[307200 x x]% + + + +Maximum allocated: 4000000 + + + diff --git a/tests/data/test3229 b/tests/data/test3229 new file mode 100644 index 0000000000..02964053f3 --- /dev/null +++ b/tests/data/test3229 @@ -0,0 +1,37 @@ + + + + +HTTP +HTTP GET +HTTP added headers + + + +# Client-side + + +http + + +Reject a custom request header larger than the request buffer + + +header "X-Large: %repeat[1048576 x x]%" + + +-K - http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + +# 100 == CURLE_TOO_LARGE + +100 + + +Maximum allocated: 6000000 + + + diff --git a/tests/unit/unit1625.c b/tests/unit/unit1625.c index 491b553954..9ca59b9402 100644 --- a/tests/unit/unit1625.c +++ b/tests/unit/unit1625.c @@ -38,7 +38,11 @@ static CURLcode test_unit1625(const char *arg) { UNITTEST_BEGIN_SIMPLE + char *large; size_t i; + const size_t large_value_len = MAX_HTTP_RESP_HEADER_SIZE; + const size_t large_prefix_len = strlen("Encoding: "); + const size_t large_suffix_len = strlen(", chunked"); static const struct check1625 list[] = { /* basic case */ { "Encoding: gzip, chunked", "Encoding:", "chunked", TRUE }, @@ -129,6 +133,20 @@ static CURLcode test_unit1625(const char *arg) if(i != CURL_ARRAYSIZE(list)) return CURLE_FAILED_INIT; + large = curlx_malloc(large_prefix_len + large_value_len + + large_suffix_len + 1); + if(!large) + return CURLE_OUT_OF_MEMORY; + + memcpy(large, "Encoding: ", large_prefix_len + 1); + memset(&large[large_prefix_len], 'a', large_value_len); + memcpy(&large[large_prefix_len + large_value_len], ", chunked", + large_suffix_len + 1); + fail_unless(Curl_compareheader(large, STRCONST("Encoding:"), + STRCONST("chunked")), + "token after 300 KiB was not found"); + curlx_free(large); + UNITTEST_END_SIMPLE } #else /* CURL_DISABLE_HTTP */