]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib1560: fix memory leak when run without UTF-8 support
authorViktor Szakats <commit@vsz.me>
Tue, 22 Jul 2025 14:44:45 +0000 (16:44 +0200)
committerViktor Szakats <commit@vsz.me>
Tue, 22 Jul 2025 15:16:32 +0000 (17:16 +0200)
The issue is missed in CI, because valgrind jobs all run with UTF-8
support.

Fixing:
```
test 1560...[URL API]
 valgrind ERROR ==13362== 104 bytes in 1 blocks are definitely lost in loss record 1 of 1
==13362==    at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13362==    by 0x48E1302: curl_dbg_calloc (in /curl/bld/lib/libcurl.so.4.8.0)
==13362==    by 0x4931D12: curl_url (in /curl/bld/lib/libcurl.so.4.8.0)
==13362==    by 0x14F658: get_parts (in /curl/bld/tests/libtest/libtests)
==13362==    by 0x150AC6: test_lib1560 (in /curl/bld/tests/libtest/libtests)
==13362==    by 0x17F5D5: main (in /curl/bld/tests/libtest/libtests)
```
Ref: https://github.com/curl/curl/actions/runs/16446352985/job/46479298080?pr=17988#step:41:3007

Follow-up to 7d1ca2e7e1a3b9d3ba70f587f6bc5e83f905afd5 #17933

Closes #17998

tests/libtest/lib1560.c

index c2ade6da48616caea34d8729f6ebe98221415757..26a98de286eff3eb8a8a931741c8adfe9d638e94 100644 (file)
@@ -1434,43 +1434,45 @@ static int setget_parts(int has_utf8)
   int error = 0;
 
   for(i = 0; setget_parts_list[i].set && !error; i++) {
-    CURLUcode rc;
     CURLU *urlp = curl_url();
     if(!urlp) {
       error++;
       break;
     }
-    if((setget_parts_list[i].getflags == CURLU_PUNYCODE ||
-        setget_parts_list[i].getflags == CURLU_PUNY2IDN) && !has_utf8) {
-      continue;
-    }
-    if(setget_parts_list[i].in)
-      rc = curl_url_set(urlp, CURLUPART_URL, setget_parts_list[i].in,
-                        setget_parts_list[i].urlflags);
-    else
-      rc = CURLUE_OK;
-    if(!rc) {
-      char *url = NULL;
-      CURLUcode uc = updateurl(urlp, setget_parts_list[i].set,
-                               setget_parts_list[i].setflags);
-
-      if(uc != setget_parts_list[i].pcode) {
-        curl_mfprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n",
-                      setget_parts_list[i].set,
-                      (int)uc, setget_parts_list[i].pcode);
-        error++;
+    if((setget_parts_list[i].getflags != CURLU_PUNYCODE &&
+        setget_parts_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) {
+      CURLUcode rc;
+      if(setget_parts_list[i].in)
+        rc = curl_url_set(urlp, CURLUPART_URL, setget_parts_list[i].in,
+                          setget_parts_list[i].urlflags);
+      else
+        rc = CURLUE_OK;
+      if(!rc) {
+        char *url = NULL;
+        CURLUcode uc = updateurl(urlp, setget_parts_list[i].set,
+                                 setget_parts_list[i].setflags);
+
+        if(uc != setget_parts_list[i].pcode) {
+          curl_mfprintf(stderr,
+                        "updateurl\nin: %s\nreturned %d (expected %d)\n",
+                        setget_parts_list[i].set, (int)uc,
+                        setget_parts_list[i].pcode);
+          error++;
+        }
+        if(!uc) {
+          if(checkparts(urlp,
+                        setget_parts_list[i].set,
+                        setget_parts_list[i].out,
+                        setget_parts_list[i].getflags))
+            error++;        /* add */
+        }
+        curl_free(url);
       }
-      if(!uc) {
-        if(checkparts(urlp, setget_parts_list[i].set, setget_parts_list[i].out,
-                      setget_parts_list[i].getflags))
-          error++;        /* add */
+      else if(rc != CURLUE_OK) {
+        curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n",
+                      setget_parts_list[i].in, (int)rc, 0);
+        error++;
       }
-      curl_free(url);
-    }
-    else if(rc != CURLUE_OK) {
-      curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n",
-                    setget_parts_list[i].in, (int)rc, 0);
-      error++;
     }
     curl_url_cleanup(urlp);
   }
@@ -1534,39 +1536,38 @@ static int get_url(int has_utf8)
   int i;
   int error = 0;
   for(i = 0; get_url_list[i].in && !error; i++) {
-    CURLUcode rc;
     CURLU *urlp = curl_url();
     if(!urlp) {
       error++;
       break;
     }
-    if((get_url_list[i].getflags == CURLU_PUNYCODE ||
-        get_url_list[i].getflags == CURLU_PUNY2IDN) && !has_utf8) {
-      continue;
-    }
-    rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in,
-                      get_url_list[i].urlflags);
-    if(!rc) {
-      char *url = NULL;
-      rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags);
+    if((get_url_list[i].getflags != CURLU_PUNYCODE &&
+        get_url_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) {
+      CURLUcode rc;
+      rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in,
+                        get_url_list[i].urlflags);
+      if(!rc) {
+        char *url = NULL;
+        rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags);
 
-      if(rc) {
-        curl_mfprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n",
-                      __FILE__, __LINE__, (int)rc, curl_url_strerror(rc),
-                      get_url_list[i].in);
-        error++;
-      }
-      else {
-        if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) {
+        if(rc) {
+          curl_mfprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n",
+                        __FILE__, __LINE__, (int)rc, curl_url_strerror(rc),
+                        get_url_list[i].in);
           error++;
         }
+        else {
+          if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) {
+            error++;
+          }
+        }
+        curl_free(url);
+      }
+      if(rc != get_url_list[i].ucode) {
+        curl_mfprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n",
+                      get_url_list[i].in, (int)rc, get_url_list[i].ucode);
+        error++;
       }
-      curl_free(url);
-    }
-    if(rc != get_url_list[i].ucode) {
-      curl_mfprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n",
-                    get_url_list[i].in, (int)rc, get_url_list[i].ucode);
-      error++;
     }
     curl_url_cleanup(urlp);
   }
@@ -1578,30 +1579,29 @@ static int get_parts(int has_utf8)
   int i;
   int error = 0;
   for(i = 0; get_parts_list[i].in && !error; i++) {
-    CURLUcode rc;
     CURLU *urlp = curl_url();
     if(!urlp) {
       error++;
       break;
     }
-    if((get_parts_list[i].getflags == CURLU_PUNYCODE ||
-        get_parts_list[i].getflags == CURLU_PUNY2IDN) && !has_utf8) {
-      continue;
-    }
-    rc = curl_url_set(urlp, CURLUPART_URL,
-                      get_parts_list[i].in,
-                      get_parts_list[i].urlflags);
-    if(rc != get_parts_list[i].ucode) {
-      curl_mfprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n",
-                    get_parts_list[i].in, (int)rc, get_parts_list[i].ucode);
-      error++;
-    }
-    else if(get_parts_list[i].ucode) {
-      /* the expected error happened */
+    if((get_parts_list[i].getflags != CURLU_PUNYCODE &&
+        get_parts_list[i].getflags != CURLU_PUNY2IDN) || has_utf8) {
+      CURLUcode rc;
+      rc = curl_url_set(urlp, CURLUPART_URL,
+                        get_parts_list[i].in,
+                        get_parts_list[i].urlflags);
+      if(rc != get_parts_list[i].ucode) {
+        curl_mfprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n",
+                      get_parts_list[i].in, (int)rc, get_parts_list[i].ucode);
+        error++;
+      }
+      else if(get_parts_list[i].ucode) {
+        /* the expected error happened */
+      }
+      else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out,
+                         get_parts_list[i].getflags))
+        error++;
     }
-    else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out,
-                       get_parts_list[i].getflags))
-      error++;
     curl_url_cleanup(urlp);
   }
   return error;