← Commit list

d7546809d5

Daniel Stenberg
Daniel Stenberg
2026-09-13
SUCCESS Duration: 392s

Subject

mime: do curl_mime_free() non-recursively

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/mime.c+22 -6
@@ -1109,20 +1109,36 @@ void Curl_mime_cleanpart(curl_mimepart *part)
}
}
-/* Recursively delete a mime handle and its parts. */
+/* Non-recursively delete a mime handle and its parts. */
void curl_mime_free(curl_mime *mime)
{
curl_mimepart *part;
- if(mime) {
- mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */
- while(mime->firstpart) {
- part = mime->firstpart;
+ if(!mime)
+ return;
+
+ mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */
+
+ while(mime) {
+ part = mime->firstpart;
+ if(part) {
mime->firstpart = part->nextpart;
+ if(part->kind == MIMEKIND_MULTIPART && part->arg &&
+ part->freefunc == mime_subparts_free) {
+ curl_mime *subparts = (curl_mime *)part->arg;
+ part->freefunc = NULL;
+ cleanup_part_content(part);
+ subparts->parent = mime->parent;
+ mime->parent = (curl_mimepart *)subparts;
+ }
Curl_mime_cleanpart(part);
curlx_free(part);
}
- curlx_free(mime);
+ else {
+ curl_mime *parent = (curl_mime *)mime->parent;
+ curlx_free(mime);
+ mime = parent;
+ }
}
}
tests/data/Makefile.am+1 -1
@@ -2100,7 +2100,7 @@ TESTCASES = \
test3401 \
\
test3500 \
- \
+ test3595 \
test4000 \
test4001 \
test4644 \
tests/data/test3595+21 -0
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+mime
+</keywords>
+</info>
+
+# Client-side
+<client>
+<tool>
+lib%TESTNUMBER
+</tool>
+<name>
+curl_mime_free
+</name>
+</client>
+
+<verify>
+</verify>
+</testcase>
tests/libtest/Makefile.inc+1 -0
@@ -331,5 +331,6 @@ TESTS_C = \
lib3207.c \
lib3208.c \
lib3231.c \
+ lib3595.c \
lib5000.c \
lib5004.c
tests/libtest/lib3595.c+70 -0
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "unitcheck.h"
+
+static CURLcode test_lib3595(const char *arg)
+{
+ UNITTEST_BEGIN_SIMPLE
+
+#if !defined(CURL_DISABLE_MIME) && \
+ (!defined(CURL_DISABLE_HTTP) || \
+ !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_IMAP))
+
+ curl_mime *root = NULL;
+ curl_mime *current = NULL;
+ curl_mime *sub = NULL;
+ curl_mimepart *part = NULL;
+ int i;
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* Create a deeply nested mime structure to verify that non-recursive
+ curl_mime_free works properly. */
+ (void)arg;
+ root = curl_mime_init(NULL);
+ fail_unless(root != NULL, "curl_mime_init root failed");
+ current = root;
+
+ for(i = 0; i < 50; i++) {
+ part = curl_mime_addpart(current);
+ fail_unless(part != NULL, "curl_mime_addpart failed");
+ sub = curl_mime_init(NULL);
+ fail_unless(sub != NULL, "curl_mime_init sub failed");
+ curl_mime_subparts(part, sub);
+ current = sub;
+ }
+
+ /* Free deep structure */
+ curl_mime_free(root);
+ curl_global_cleanup();
+#else
+ (void)arg;
+#endif
+
+ UNITTEST_END_SIMPLE
+}