Curl_fillreadbuffer: avoid double-free trailer buf on error

Reviewed-by: Jay Satiro
Reported-by: Thomas Vegas

Closes #4307
This commit is contained in:
Daniel Stenberg 2019-09-05 00:08:21 +02:00
parent 74e152f119
commit c4c9e070f3
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 17 additions and 12 deletions

View File

@ -1146,10 +1146,14 @@ Curl_send_buffer *Curl_add_buffer_init(void)
*/ */
void Curl_add_buffer_free(Curl_send_buffer **inp) void Curl_add_buffer_free(Curl_send_buffer **inp)
{ {
Curl_send_buffer *in = *inp; Curl_send_buffer *in;
if(in) /* deal with NULL input */ if(!inp)
return;
in = *inp;
if(in) { /* deal with NULL input */
free(in->buffer); free(in->buffer);
free(in); free(in);
}
*inp = NULL; *inp = NULL;
} }
@ -1720,7 +1724,7 @@ enum proxy_use {
will return an error code if one of the headers is will return an error code if one of the headers is
not formatted correctly */ not formatted correctly */
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
Curl_send_buffer *buffer, Curl_send_buffer **buffer,
struct Curl_easy *handle) struct Curl_easy *handle)
{ {
char *ptr = NULL; char *ptr = NULL;
@ -1746,7 +1750,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
/* only add correctly formatted trailers */ /* only add correctly formatted trailers */
ptr = strchr(trailers->data, ':'); ptr = strchr(trailers->data, ':');
if(ptr && *(ptr + 1) == ' ') { if(ptr && *(ptr + 1) == ' ') {
result = Curl_add_bufferf(&buffer, "%s%s", trailers->data, result = Curl_add_bufferf(buffer, "%s%s", trailers->data,
endofline_native); endofline_native);
if(result) if(result)
return result; return result;
@ -1755,7 +1759,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
infof(handle, "Malformatted trailing header ! Skipping trailer."); infof(handle, "Malformatted trailing header ! Skipping trailer.");
trailers = trailers->next; trailers = trailers->next;
} }
result = Curl_add_buffer(&buffer, endofline_network, result = Curl_add_buffer(buffer, endofline_network,
strlen(endofline_network)); strlen(endofline_network));
return result; return result;
} }

View File

@ -75,7 +75,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
bool is_connect, bool is_connect,
Curl_send_buffer *req_buffer); Curl_send_buffer *req_buffer);
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
Curl_send_buffer *buffer, Curl_send_buffer **buffer,
struct Curl_easy *handle); struct Curl_easy *handle);
/* protocol-specific functions set up to be called by the main engine */ /* protocol-specific functions set up to be called by the main engine */

View File

@ -176,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
if(data->state.trailers_state == TRAILERS_INITIALIZED) { if(data->state.trailers_state == TRAILERS_INITIALIZED) {
struct curl_slist *trailers = NULL; struct curl_slist *trailers = NULL;
CURLcode c; CURLcode result;
int trailers_ret_code; int trailers_ret_code;
/* at this point we already verified that the callback exists /* at this point we already verified that the callback exists
@ -195,17 +195,18 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
data->set.trailer_data); data->set.trailer_data);
Curl_set_in_callback(data, false); Curl_set_in_callback(data, false);
if(trailers_ret_code == CURL_TRAILERFUNC_OK) { if(trailers_ret_code == CURL_TRAILERFUNC_OK) {
c = Curl_http_compile_trailers(trailers, data->state.trailers_buf, data); result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf,
data);
} }
else { else {
failf(data, "operation aborted by trailing headers callback"); failf(data, "operation aborted by trailing headers callback");
*nreadp = 0; *nreadp = 0;
c = CURLE_ABORTED_BY_CALLBACK; result = CURLE_ABORTED_BY_CALLBACK;
} }
if(c != CURLE_OK) { if(result) {
Curl_add_buffer_free(&data->state.trailers_buf); Curl_add_buffer_free(&data->state.trailers_buf);
curl_slist_free_all(trailers); curl_slist_free_all(trailers);
return c; return result;
} }
infof(data, "Successfully compiled trailers.\r\n"); infof(data, "Successfully compiled trailers.\r\n");
curl_slist_free_all(trailers); curl_slist_free_all(trailers);