From: Jiří Hruška Date: Mon, 20 Nov 2023 08:26:59 +0000 (+0100) Subject: transfer: avoid calling the read callback again after EOF X-Git-Tag: curl-8_5_0~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a095da1f3c836fa7e06510720555746b1353506;p=thirdparty%2Fcurl.git transfer: avoid calling the read callback again after EOF Regression since 7f43f3dc5994d01b12 (7.84.0) Bug: https://curl.se/mail/lib-2023-11/0017.html Closes #12363 --- diff --git a/lib/transfer.c b/lib/transfer.c index 8e8158e64a..2c3d84c433 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -163,9 +163,9 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, { size_t buffersize = bytes; size_t nread; - curl_read_callback readfunc = NULL; void *extra_data = NULL; + int eof_index = 0; #ifndef CURL_DISABLE_HTTP if(data->state.trailers_state == TRAILERS_INITIALIZED) { @@ -223,6 +223,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, */ readfunc = trailers_read; extra_data = (void *)data; + eof_index = 1; } else #endif @@ -231,10 +232,15 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, extra_data = data->state.in; } - Curl_set_in_callback(data, true); - nread = readfunc(data->req.upload_fromhere, 1, - buffersize, extra_data); - Curl_set_in_callback(data, false); + if(!data->req.fread_eof[eof_index]) { + Curl_set_in_callback(data, true); + nread = readfunc(data->req.upload_fromhere, 1, buffersize, extra_data); + Curl_set_in_callback(data, false); + /* make sure the callback is not called again after EOF */ + data->req.fread_eof[eof_index] = !nread; + } + else + nread = 0; if(nread == CURL_READFUNC_ABORT) { failf(data, "operation aborted by callback"); diff --git a/lib/urldata.h b/lib/urldata.h index 1e9a53fd9e..e5dc324826 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -733,6 +733,8 @@ struct SingleRequest { struct curltime last_sndbuf_update; /* last time readwrite_upload called win_update_buffer_size */ #endif + char fread_eof[2]; /* the body read callback (index 0) returned EOF or + the trailer read callback (index 1) returned EOF */ #ifndef CURL_DISABLE_COOKIES unsigned char setcookies; #endif