]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
transfer: avoid calling the read callback again after EOF
authorJiří Hruška <jirka@fud.cz>
Mon, 20 Nov 2023 08:26:59 +0000 (09:26 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 21 Nov 2023 06:58:53 +0000 (07:58 +0100)
Regression since 7f43f3dc5994d01b12 (7.84.0)

Bug: https://curl.se/mail/lib-2023-11/0017.html

Closes #12363

lib/transfer.c
lib/urldata.h

index 8e8158e64ab1178c3c4a55f01e4be974ce454449..2c3d84c4331f441bebf0af0e7fa396d89d5befff 100644 (file)
@@ -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");
index 1e9a53fd9e0dfa9a5e7322121ebb5f8e1cea1267..e5dc324826edca65010051224d2da71c515b6c39 100644 (file)
@@ -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