]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_operate: more transfer cleanup after parallel transfer fail
authorDaniel Stenberg <daniel@haxx.se>
Mon, 17 Oct 2022 09:44:13 +0000 (11:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 18 Oct 2022 06:41:38 +0000 (08:41 +0200)
In some circumstances when doing parallel transfers, the
single_transfer_cleanup() would not be called and then 'inglob' could
leak.

Test 496 verifies

Reported-by: Trail of Bits
Closes #9749

src/tool_operate.c
src/tool_operate.h
src/tool_operhlp.c
tests/data/Makefile.inc
tests/data/test496 [new file with mode: 0644]

index c64b17d063c8dbe1806648e75c38f6983052aeb0..08e71fdfded7f7dd783a744d4007e758b2188970 100644 (file)
@@ -350,6 +350,26 @@ static void AmigaSetComment(struct per_transfer *per,
 /* When doing serial transfers, we use a single fixed error area */
 static char global_errorbuffer[CURL_ERROR_SIZE];
 
+void single_transfer_cleanup(struct OperationConfig *config)
+{
+  if(config) {
+    struct State *state = &config->state;
+    if(state->urls) {
+      /* Free list of remaining URLs */
+      glob_cleanup(state->urls);
+      state->urls = NULL;
+    }
+    Curl_safefree(state->outfiles);
+    Curl_safefree(state->httpgetfields);
+    Curl_safefree(state->uploadfile);
+    if(state->inglob) {
+      /* Free list of globbed upload files */
+      glob_cleanup(state->inglob);
+      state->inglob = NULL;
+    }
+  }
+}
+
 /*
  * Call this after a transfer has completed.
  */
@@ -666,26 +686,6 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
   return result;
 }
 
-static void single_transfer_cleanup(struct OperationConfig *config)
-{
-  if(config) {
-    struct State *state = &config->state;
-    if(state->urls) {
-      /* Free list of remaining URLs */
-      glob_cleanup(state->urls);
-      state->urls = NULL;
-    }
-    Curl_safefree(state->outfiles);
-    Curl_safefree(state->httpgetfields);
-    Curl_safefree(state->uploadfile);
-    if(state->inglob) {
-      /* Free list of globbed upload files */
-      glob_cleanup(state->inglob);
-      state->inglob = NULL;
-    }
-  }
-}
-
 /*
  * Return the protocol token for the scheme used in the given URL
  */
index 56e002a3f2bb4ba2872d643a8b8676e0715138be..c714da1bc25fe3806d113d74b5d8e9f66c3ef924 100644 (file)
@@ -76,6 +76,7 @@ struct per_transfer {
 };
 
 CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]);
+void single_transfer_cleanup(struct OperationConfig *config);
 
 extern struct per_transfer *transfers; /* first node */
 
index f41406f3ce42058e118a2795d589ca8a338c2704..eb58772fb9c9b98e309c8c8c381f985bf846dae9 100644 (file)
@@ -22,6 +22,7 @@
  *
  ***************************************************************************/
 #include "tool_setup.h"
+#include "tool_operate.h"
 
 #include "strcase.h"
 
@@ -51,6 +52,7 @@ void clean_getout(struct OperationConfig *config)
     }
     config->url_list = NULL;
   }
+  single_transfer_cleanup(config);
 }
 
 bool output_expected(const char *url, const char *uploadfile)
index 722f4a8ec36e04660cdd53362b678a3d23dda253..8195ad7ecc5712ae69093bf354ac83c7746f0386 100644 (file)
@@ -73,7 +73,7 @@ test430 test431 test432 test433 test434 test435 test436 \
 \
 test440 test441 test442 test443 test444 \
 \
-test490 test491 test492 test493 test494 test495 \
+test490 test491 test492 test493 test494 test495 test496 \
 \
 test500 test501 test502 test503 test504 test505 test506 test507 test508 \
 test509 test510 test511 test512 test513 test514 test515 test516 test517 \
diff --git a/tests/data/test496 b/tests/data/test496
new file mode 100644 (file)
index 0000000..19050f3
--- /dev/null
@@ -0,0 +1,36 @@
+<testcase>
+<info>
+<keywords>
+curl tool
+cmdline
+parallel
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<name>
+parallel upload missing file
+</name>
+ <command>
+0 -Z -Tz
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+26
+</errorcode>
+</verify>
+</testcase>