diff --git a/CHANGES b/CHANGES index 1bc88a298..cb501bb63 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,13 @@ Changelog +Daniel S (16 Nov 2007) +- Ates Goral identified a problem in http.c:add_buffer_send() when a debug + callback was used, as it could wrongly pass on a bad size for the outgoing + HTTP header. The bad size would be a very large value as it was a wrapped + size_t content. This happened when the whole HTTP request failed to get sent + in one single send. http://curl.haxx.se/mail/lib-2007-11/0165.html + Daniel S (15 Nov 2007) - Fixed yet another remaining problem with doing SFTP directory listings on a re-used persistent connection. Mentioned by Immanuel Gregoire on the mailing diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 2be825413..5d71c7f50 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -4,7 +4,7 @@ Curl and libcurl 7.17.2 Command line options: 121 curl_easy_setopt() options: 147 Public functions in libcurl: 55 - Public web site mirrors: 43 + Public web site mirrors: 42 Known libcurl bindings: 36 Contributors: 597 @@ -21,6 +21,8 @@ This release includes the following bugfixes: o SFTP and SCP use persistent connections o segfault on bad URL o variable wrapping when using absolutely huge send buffer sizes + o variable wrapping when using debug callback and the HTTP request wasn't sent + in one go This release includes the following known bugs: @@ -39,6 +41,6 @@ This release would not have looked like this without help, code, reports and advice from friends like these: Dan Fandrich, Gisle Vanem, Toby Peterson, Yang Tse, Daniel Black, - Robin Johnson + Robin Johnson, Michal Marek, Ates Goral Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/http.c b/lib/http.c index eba69bdac..d0d3bc1ea 100644 --- a/lib/http.c +++ b/lib/http.c @@ -932,6 +932,7 @@ CURLcode add_buffer_send(send_buffer *in, struct HTTP *http = conn->data->reqdata.proto.http; size_t sendsize; curl_socket_t sockfd; + size_t headersize; DEBUGASSERT(socketindex <= SECONDARYSOCKET); @@ -943,10 +944,13 @@ CURLcode add_buffer_send(send_buffer *in, ptr = in->buffer; size = in->size_used; - DEBUGASSERT(size - included_body_bytes > 0); + headersize = size - included_body_bytes; /* the initial part that isn't body + is header */ + + DEBUGASSERT(headersize > 0); #ifdef CURL_DOES_CONVERSIONS - res = Curl_convert_to_network(conn->data, ptr, size - included_body_bytes); + res = Curl_convert_to_network(conn->data, ptr, headersize); /* Curl_convert_to_network calls failf if unsuccessful */ if(res != CURLE_OK) { /* conversion failed, free memory and return to the caller */ @@ -981,20 +985,29 @@ CURLcode add_buffer_send(send_buffer *in, res = Curl_write(conn, sockfd, ptr, sendsize, &amount); if(CURLE_OK == res) { + /* + * Note that we may not send the entire chunk at once, and we have a set + * number of data bytes at the end of the big buffer (out of which we may + * only send away a part). + */ + /* how much of the header that was sent */ + size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount; + size_t bodylen = amount - headlen; if(conn->data->set.verbose) { /* this data _may_ contain binary stuff */ - Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, - (size_t)(amount-included_body_bytes), conn); - if(included_body_bytes) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn); + if((size_t)amount > headlen) { + /* there was body data sent beyond the initial header part, pass that + on to the debug callback too */ Curl_debug(conn->data, CURLINFO_DATA_OUT, - ptr+amount-included_body_bytes, - (size_t)included_body_bytes, conn); + ptr+headlen, bodylen, conn); + } } - if(included_body_bytes) + if(bodylen) /* since we sent a piece of the body here, up the byte counter for it accordingly */ - http->writebytecount = included_body_bytes; + http->writebytecount += bodylen; *bytes_written += amount;