From 55dbcb061d6ee733a1ba12d8634c85691a3010e0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 Sep 2018 11:48:53 +0200 Subject: http: made Curl_add_buffer functions take a pointer-pointer ... so that they can clear the original pointer on failure, which makes the error-paths and their cleanups easier. Closes #2992 --- lib/http.c | 112 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 52 deletions(-) (limited to 'lib/http.c') diff --git a/lib/http.c b/lib/http.c index e727ed823..c1d0d68cd 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1094,11 +1094,13 @@ Curl_send_buffer *Curl_add_buffer_init(void) /* * Curl_add_buffer_free() frees all associated resources. */ -void Curl_add_buffer_free(Curl_send_buffer *buff) +void Curl_add_buffer_free(Curl_send_buffer **inp) { - if(buff) /* deal with NULL input */ - free(buff->buffer); - free(buff); + Curl_send_buffer *in = *inp; + if(in) /* deal with NULL input */ + free(in->buffer); + free(in); + *inp = NULL; } /* @@ -1107,7 +1109,7 @@ void Curl_add_buffer_free(Curl_send_buffer *buff) * * Returns CURLcode */ -CURLcode Curl_add_buffer_send(Curl_send_buffer *in, +CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, struct connectdata *conn, /* add the number of sent bytes to this @@ -1128,6 +1130,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, size_t sendsize; curl_socket_t sockfd; size_t headersize; + Curl_send_buffer *in = *inp; DEBUGASSERT(socketindex <= SECONDARYSOCKET); @@ -1148,7 +1151,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, /* Curl_convert_to_network calls failf if unsuccessful */ if(result) { /* conversion failed, free memory and return to the caller */ - Curl_add_buffer_free(in); + Curl_add_buffer_free(inp); return result; } @@ -1172,7 +1175,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, result = Curl_get_upload_buffer(data); if(result) { /* malloc failed, free memory and return to the caller */ - Curl_add_buffer_free(in); + Curl_add_buffer_free(&in); return result; } memcpy(data->state.ulbuf, ptr, sendsize); @@ -1256,7 +1259,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, Curl_pipeline_leave_write(conn); } } - Curl_add_buffer_free(in); + Curl_add_buffer_free(&in); return result; } @@ -1265,31 +1268,35 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, /* * add_bufferf() add the formatted input to the buffer. */ -CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...) +CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...) { char *s; va_list ap; + Curl_send_buffer *in = *inp; va_start(ap, fmt); s = vaprintf(fmt, ap); /* this allocs a new string to append */ va_end(ap); if(s) { - CURLcode result = Curl_add_buffer(in, s, strlen(s)); + CURLcode result = Curl_add_buffer(inp, s, strlen(s)); free(s); return result; } /* If we failed, we cleanup the whole buffer and return error */ free(in->buffer); free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } /* - * add_buffer() appends a memory chunk to the existing buffer + * Curl_add_buffer() appends a memory chunk to the existing buffer */ -CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) +CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, + size_t size) { char *new_rb; + Curl_send_buffer *in = *inp; if(~size < in->size_used) { /* If resulting used size of send buffer would wrap size_t, cleanup @@ -1297,6 +1304,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) size will fit into a single allocatable memory chunk */ Curl_safefree(in->buffer); free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } @@ -1323,6 +1331,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) if(!new_rb) { /* If we failed, we cleanup the whole buffer and return error */ free(in); + *inp = NULL; return CURLE_OUT_OF_MEMORY; } @@ -1484,11 +1493,11 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn) if(!req_buffer) return CURLE_OUT_OF_MEMORY; - result = Curl_add_bufferf(req_buffer, proxy_header); + result = Curl_add_bufferf(&req_buffer, proxy_header); if(result) return result; - result = Curl_add_buffer_send(req_buffer, + result = Curl_add_buffer_send(&req_buffer, conn, &conn->data->info.request_size, 0, @@ -1561,8 +1570,7 @@ CURLcode Curl_http_done(struct connectdata *conn, return CURLE_OK; if(http->send_buffer) { - Curl_add_buffer_free(http->send_buffer); - http->send_buffer = NULL; /* clear the pointer */ + Curl_add_buffer_free(&http->send_buffer); } Curl_http2_done(conn, premature); @@ -1653,8 +1661,8 @@ static CURLcode expect100(struct Curl_easy *data, Curl_compareheader(ptr, "Expect:", "100-continue"); } else { - result = Curl_add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); + result = Curl_add_bufferf(&req_buffer, + "Expect: 100-continue\r\n"); if(!result) data->state.expect100header = TRUE; } @@ -1785,7 +1793,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, !strcasecompare(data->state.first_host, conn->host.name))) ; else { - result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); + result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data); } if(semicolonp) *semicolonp = ';'; /* put back the semicolon */ @@ -1854,7 +1862,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data, tm->tm_min, tm->tm_sec); - result = Curl_add_buffer(req_buffer, datestr, strlen(datestr)); + result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr)); return result; } @@ -2419,7 +2427,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* add the main request stuff */ /* GET/HEAD/POST/PUT */ - result = Curl_add_bufferf(req_buffer, "%s ", request); + result = Curl_add_bufferf(&req_buffer, "%s ", request); if(result) return result; @@ -2428,16 +2436,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* url */ if(paste_ftp_userpwd) - result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s", + result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s", conn->user, conn->passwd, ppath + sizeof("ftp://") - 1); else - result = Curl_add_buffer(req_buffer, ppath, strlen(ppath)); + result = Curl_add_buffer(&req_buffer, ppath, strlen(ppath)); if(result) return result; result = - Curl_add_bufferf(req_buffer, + Curl_add_bufferf(&req_buffer, "%s" /* ftp typecode (;type=x) */ " HTTP/%s\r\n" /* HTTP version */ "%s" /* host */ @@ -2518,11 +2526,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) while(co) { if(co->value) { if(0 == count) { - result = Curl_add_bufferf(req_buffer, "Cookie: "); + result = Curl_add_bufferf(&req_buffer, "Cookie: "); if(result) break; } - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "%s%s=%s", count?"; ":"", co->name, co->value); if(result) @@ -2535,15 +2543,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } if(addcookies && !result) { if(!count) - result = Curl_add_bufferf(req_buffer, "Cookie: "); + result = Curl_add_bufferf(&req_buffer, "Cookie: "); if(!result) { - result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"", + result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"", addcookies); count++; } } if(count && !result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; @@ -2577,7 +2585,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if((postsize != -1) && !data->req.upload_chunky && (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* only add Content-Length if not uploading chunked */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2590,7 +2598,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */ if(result) return result; @@ -2598,7 +2606,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) Curl_pgrsSetUploadSize(data, postsize); /* this sends the buffer and frees all the buffer resources */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending PUT request"); @@ -2616,11 +2624,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* This is form posting using mime data. */ if(conn->bits.authneg) { /* nothing to post! */ - result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n"); + result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n"); if(result) return result; - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending POST request"); @@ -2640,7 +2648,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2652,7 +2660,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) struct curl_slist *hdr; for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) { - result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data); + result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data); if(result) return result; } @@ -2676,7 +2684,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) data->state.expect100header = FALSE; /* make the request end in a true CRLF */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; @@ -2689,7 +2697,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http->sending = HTTPSEND_BODY; /* this sends the buffer and frees all the buffer resources */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) failf(data, "Failed sending POST request"); @@ -2719,7 +2727,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", postsize); if(result) @@ -2727,7 +2735,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } if(!Curl_checkheaders(conn, "Content-Type")) { - result = Curl_add_bufferf(req_buffer, + result = Curl_add_bufferf(&req_buffer, "Content-Type: application/" "x-www-form-urlencoded\r\n"); if(result) @@ -2765,31 +2773,31 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) is no magic limit but only set to prevent really huge POSTs to get the data duplicated with malloc() and family. */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; if(!data->req.upload_chunky) { /* We're not sending it 'chunked', append it to the request already now to reduce the number if send() calls */ - result = Curl_add_buffer(req_buffer, data->set.postfields, + result = Curl_add_buffer(&req_buffer, data->set.postfields, (size_t)postsize); included_body = postsize; } else { if(postsize) { /* Append the POST data chunky-style */ - result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize); + result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize); if(!result) { - result = Curl_add_buffer(req_buffer, data->set.postfields, + result = Curl_add_buffer(&req_buffer, data->set.postfields, (size_t)postsize); if(!result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); included_body = postsize + 2; } } if(!result) - result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); + result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); /* 0 CR LF CR LF */ included_body += 5; } @@ -2811,20 +2819,20 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* set the upload size to the progress meter */ Curl_pgrsSetUploadSize(data, http->postsize); - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; } } else { - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ if(result) return result; if(data->req.upload_chunky && conn->bits.authneg) { /* Chunky upload is selected and we're negotiating auth still, send end-of-data only */ - result = Curl_add_buffer(req_buffer, + result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); /* 0 CR LF CR LF */ if(result) @@ -2845,7 +2853,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } } /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, (size_t)included_body, FIRSTSOCKET); if(result) @@ -2857,12 +2865,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) break; default: - result = Curl_add_buffer(req_buffer, "\r\n", 2); + result = Curl_add_buffer(&req_buffer, "\r\n", 2); if(result) return result; /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, 0, FIRSTSOCKET); if(result) -- cgit v1.2.3