mirror of
https://github.com/curl/curl.git
synced 2026-04-15 00:51:42 +03:00
http: only accept ';' as a separator for custom headers
When parsing incoming headers, they need to have a plain normal colon. Previously out of convenience we used the same parser function for both cases (incoming + custom set headers via the API) which made the function too liberal for incoming HTTP traffic. Closes #19200
This commit is contained in:
parent
2edce44065
commit
0d1d35fa34
1 changed files with 52 additions and 22 deletions
74
lib/http.c
74
lib/http.c
|
|
@ -277,14 +277,13 @@ static bool http_header_is_empty(const char *header)
|
|||
|
||||
/*
|
||||
* Strip off leading and trailing whitespace from the value in the given HTTP
|
||||
* header line and return a strdup()ed copy. Returns NULL in case of
|
||||
* allocation failure or bad input. Returns an empty string if the header
|
||||
* value consists entirely of whitespace.
|
||||
* header line and return a strdup()ed copy in 'valp' - returns an empty
|
||||
* string if the header value consists entirely of whitespace.
|
||||
*
|
||||
* If the header is provided as "name;", ending with a semicolon, it must
|
||||
* return a blank string.
|
||||
* If the header is provided as "name;", ending with a semicolon, it returns a
|
||||
* blank string.
|
||||
*/
|
||||
char *Curl_copy_header_value(const char *header)
|
||||
static CURLcode copy_custom_value(const char *header, char **valp)
|
||||
{
|
||||
struct Curl_str out;
|
||||
|
||||
|
|
@ -294,9 +293,37 @@ char *Curl_copy_header_value(const char *header)
|
|||
curlx_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
|
||||
curlx_str_trimblanks(&out);
|
||||
|
||||
return Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
|
||||
*valp = Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
|
||||
if(*valp)
|
||||
return CURLE_OK;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* bad input */
|
||||
*valp = NULL;
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip off leading and trailing whitespace from the value in the given HTTP
|
||||
* header line and return a strdup()ed copy in 'valp' - returns an empty
|
||||
* string if the header value consists entirely of whitespace.
|
||||
*
|
||||
* This function MUST be used after the header has already been confirmed to
|
||||
* lead with "word:".
|
||||
*/
|
||||
char *Curl_copy_header_value(const char *header)
|
||||
{
|
||||
struct Curl_str out;
|
||||
|
||||
/* find the end of the header name */
|
||||
if(!curlx_str_until(&header, &out, MAX_HTTP_RESP_HEADER_SIZE, ':') &&
|
||||
!curlx_str_single(&header, ':')) {
|
||||
curlx_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
|
||||
curlx_str_trimblanks(&out);
|
||||
return Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
|
||||
}
|
||||
/* bad input, should never happen */
|
||||
DEBUGASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1906,9 +1933,10 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
|
|||
custom Host: header if this is NOT a redirect, as setting Host: in the
|
||||
redirected request is being out on thin ice. Except if the hostname
|
||||
is the same as the first one! */
|
||||
char *cookiehost = Curl_copy_header_value(ptr);
|
||||
if(!cookiehost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
char *cookiehost;
|
||||
CURLcode result = copy_custom_value(ptr, &cookiehost);
|
||||
if(result)
|
||||
return result;
|
||||
if(!*cookiehost)
|
||||
/* ignore empty data */
|
||||
free(cookiehost);
|
||||
|
|
@ -2657,7 +2685,6 @@ static CURLcode http_add_connection_hd(struct Curl_easy *data,
|
|||
const char *sep = "Connection: ";
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t rlen = curlx_dyn_len(req);
|
||||
char *value;
|
||||
bool skip;
|
||||
|
||||
/* Add the 1st custom "Connection: " header, if there is one */
|
||||
|
|
@ -2665,9 +2692,10 @@ static CURLcode http_add_connection_hd(struct Curl_easy *data,
|
|||
if(curl_strnequal(head->data, "Connection", 10) &&
|
||||
Curl_headersep(head->data[10]) &&
|
||||
!http_header_is_empty(head->data)) {
|
||||
value = Curl_copy_header_value(head->data);
|
||||
if(!value)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
char *value;
|
||||
result = copy_custom_value(head->data, &value);
|
||||
if(result)
|
||||
return result;
|
||||
result = curlx_dyn_addf(req, "%s%s", sep, value);
|
||||
sep = ", ";
|
||||
free(value);
|
||||
|
|
@ -3346,11 +3374,11 @@ static CURLcode http_header_p(struct Curl_easy *data,
|
|||
#endif
|
||||
if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) {
|
||||
char *auth = Curl_copy_header_value(hd);
|
||||
CURLcode result;
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_http_input_auth(data, TRUE, auth);
|
||||
free(auth);
|
||||
CURLcode result = auth ? CURLE_OK : CURLE_OUT_OF_MEMORY;
|
||||
if(!result) {
|
||||
result = Curl_http_input_auth(data, TRUE, auth);
|
||||
free(auth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#ifdef USE_SPNEGO
|
||||
|
|
@ -3525,9 +3553,11 @@ static CURLcode http_header_w(struct Curl_easy *data,
|
|||
if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) {
|
||||
char *auth = Curl_copy_header_value(hd);
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_http_input_auth(data, FALSE, auth);
|
||||
free(auth);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else {
|
||||
result = Curl_http_input_auth(data, FALSE, auth);
|
||||
free(auth);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue