]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl/add_parallel_transfers: better error handling
authorDaniel Stenberg <daniel@haxx.se>
Wed, 12 Oct 2022 06:42:57 +0000 (08:42 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 14 Oct 2022 06:15:55 +0000 (08:15 +0200)
1 - consider the transfer handled at once when in the function, to avoid
    the same list entry to get added more than once in rare error
    situations

2 - set the ERRORBUFFER for the handle first after it has been added
    successfully

Reported-by: Trail of Bits
Closes #9729

src/tool_operate.c

index 544c04a29f1fe97f2a10b12e3573042d46f89351..c64b17d063c8dbe1806648e75c38f6983052aeb0 100644 (file)
@@ -2192,17 +2192,15 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
       sleeping = TRUE;
       continue;
     }
+    per->added = TRUE;
 
     result = pre_transfer(global, per);
     if(result)
       return result;
 
-    errorbuf = per->errorbuffer;
-    if(!errorbuf) {
-      errorbuf = malloc(CURL_ERROR_SIZE);
-      if(!errorbuf)
-        return CURLE_OUT_OF_MEMORY;
-    }
+    errorbuf = malloc(CURL_ERROR_SIZE);
+    if(!errorbuf)
+      return CURLE_OUT_OF_MEMORY;
 
     /* parallel connect means that we don't set PIPEWAIT since pipewait
        will make libcurl prefer multiplexing */
@@ -2212,19 +2210,21 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
     (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb);
     (void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per);
     (void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L);
-    (void)curl_easy_setopt(per->curl, CURLOPT_ERRORBUFFER, errorbuf);
 
     mcode = curl_multi_add_handle(multi, per->curl);
     if(mcode) {
-      free(errorbuf);
-      return CURLE_OUT_OF_MEMORY;
+      DEBUGASSERT(mcode == CURLM_OUT_OF_MEMORY);
+      result = CURLE_OUT_OF_MEMORY;
     }
 
-    result = create_transfer(global, share, &getadded);
+    if(!result)
+      result = create_transfer(global, share, &getadded);
     if(result) {
       free(errorbuf);
       return result;
     }
+    errorbuf[0] = 0;
+    (void)curl_easy_setopt(per->curl, CURLOPT_ERRORBUFFER, errorbuf);
     per->errorbuffer = errorbuf;
     per->added = TRUE;
     all_added++;