diff options
| author | robot-contrib <[email protected]> | 2022-07-12 12:03:53 +0300 |
|---|---|---|
| committer | robot-contrib <[email protected]> | 2022-07-12 12:03:53 +0300 |
| commit | eeebfbedb3ea4cab5c0aac178b683b7dd26b0bf6 (patch) | |
| tree | 4783d362be8e22467d0f5eb581ce6f65e33acb04 /contrib/libs/curl/lib/headers.c | |
| parent | 4213b519b93b5e3d657bc362837adfea82579dcc (diff) | |
Update contrib/libs/curl to 7.84.0
Diffstat (limited to 'contrib/libs/curl/lib/headers.c')
| -rw-r--r-- | contrib/libs/curl/lib/headers.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/contrib/libs/curl/lib/headers.c b/contrib/libs/curl/lib/headers.c index 226c696be6b..154623737a9 100644 --- a/contrib/libs/curl/lib/headers.c +++ b/contrib/libs/curl/lib/headers.c @@ -18,6 +18,8 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * + * SPDX-License-Identifier: curl + * ***************************************************************************/ #include "curl_setup.h" @@ -32,7 +34,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API) +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HEADERS_API) /* Generate the curl_header struct for the user. This function MUST assign all struct fields in the output struct. */ @@ -216,6 +218,57 @@ static CURLcode namevalue(char *header, size_t hlen, unsigned int type, return CURLE_OK; } +static CURLcode unfold_value(struct Curl_easy *data, const char *value, + size_t vlen) /* length of the incoming header */ +{ + struct Curl_header_store *hs; + struct Curl_header_store *newhs; + size_t olen; /* length of the old value */ + size_t oalloc; /* length of the old name + value + separator */ + size_t offset; + DEBUGASSERT(data->state.prevhead); + hs = data->state.prevhead; + olen = strlen(hs->value); + offset = hs->value - hs->buffer; + oalloc = olen + offset + 1; + + /* skip all trailing space letters */ + while(vlen && ISSPACE(value[vlen - 1])) + vlen--; + + /* save only one leading space */ + while((vlen > 1) && ISSPACE(value[0]) && ISSPACE(value[1])) { + vlen--; + value++; + } + + /* since this header block might move in the realloc below, it needs to + first be unlinked from the list and then re-added again after the + realloc */ + Curl_llist_remove(&data->state.httphdrs, &hs->node, NULL); + + /* new size = struct + new value length + old name+value length */ + newhs = Curl_saferealloc(hs, sizeof(*hs) + vlen + oalloc + 1); + if(!newhs) + return CURLE_OUT_OF_MEMORY; + /* ->name' and ->value point into ->buffer (to keep the header allocation + in a single memory block), which now potentially have moved. Adjust + them. */ + newhs->name = newhs->buffer; + newhs->value = &newhs->buffer[offset]; + + /* put the data at the end of the previous data, not the newline */ + memcpy(&newhs->value[olen], value, vlen); + newhs->value[olen + vlen] = 0; /* zero terminate at newline */ + + /* insert this node into the list of headers */ + Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail, + newhs, &newhs->node); + data->state.prevhead = newhs; + return CURLE_OK; +} + + /* * Curl_headers_push() gets passed a full HTTP header to store. It gets called * immediately before the header callback. The header is CRLF terminated. @@ -242,6 +295,15 @@ CURLcode Curl_headers_push(struct Curl_easy *data, const char *header, } hlen = end - header + 1; + if((header[0] == ' ') || (header[0] == '\t')) { + if(data->state.prevhead) + /* line folding, append value to the previous header's value */ + return unfold_value(data, header, hlen); + else + /* can't unfold without a previous header */ + return CURLE_BAD_FUNCTION_ARGUMENT; + } + hs = calloc(1, sizeof(*hs) + hlen); if(!hs) return CURLE_OUT_OF_MEMORY; @@ -260,7 +322,7 @@ CURLcode Curl_headers_push(struct Curl_easy *data, const char *header, /* insert this node into the list of headers */ Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail, hs, &hs->node); - + data->state.prevhead = hs; return CURLE_OK; fail: free(hs); |
