[PECL-CVS] [pecl-mail-mailparse] master: Fix memory leak of parameter name after an RFC2231 parameter

[email protected] (Ilia Alshanetsky via Remi Collet) Thu, 18 Jun 2026 06:49:16 +0000
Newsgroups php.pecl.cvs
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Committer: Remi Collet (remicollet)
Date: 2026-06-18T08:49:02+02:00

Commit: https://github.com/php/pecl-mail-mailparse/commit/b79ec8ad0d4bfdd3a27c4e9e672bdbdaa7c840fe
Raw diff: https://github.com/php/pecl-mail-mailparse/commit/b79ec8ad0d4bfdd3a27c4e9e672bdbdaa7c840fe.diff

Fix memory leak of parameter name after an RFC2231 parameter

currentencoded was set to 1 on the first RFC2231 (name*N) parameter and
never reset, so every later parameter took the is_rfc2231_name finalize
path. When a later plain parameter arrived, neither the !currentencoded
branch (stale 1) nor the namechanged branch (stale 0) consumed its name,
so the emalloc'd name was neither stored nor freed. A header such as
"Content-Type: x/y; a*0=\"foo\"; b=\"bar\"" leaked one allocation per
plain-after-encoded parameter.

Reset currentencoded per parameter so it reflects the current parameter
only; the plain parameter now takes the !currentencoded branch, which
stores and frees its name.

Changed paths:
  A  tests/rfc2231_plain_after_encoded.phpt
  M  package.xml
  M  php_mailparse_mime.c


Diff:

diff --git a/package.xml b/package.xml
index 6060137..a8a31f3 100644
--- a/package.xml
+++ b/package.xml
@@ -99,8 +99,9 @@ It can deal with rfc822 and rfc2045 (MIME) compliant messages.
     <file name="gh30.phpt" role="test" />
     <file name="gh43.phpt" role="test" />
     <file name="gh44.phpt" role="test" />
-    <file name="parse_test_messages.phpt" role="test" />
     <file name="mime_nesting_depth.phpt" role="test" />
+    <file name="parse_test_messages.phpt" role="test" />
+    <file name="rfc2231_plain_after_encoded.phpt" role="test" />
    </dir> <!-- //tests -->
    <file name="config.m4" role="src" />
    <file name="config.w32" role="src" />
diff --git a/php_mailparse_mime.c b/php_mailparse_mime.c
index 28d0dd7..72fe510 100644
--- a/php_mailparse_mime.c
+++ b/php_mailparse_mime.c
@@ -198,6 +198,7 @@ static struct php_mimeheader_with_attributes *php_mimeheader_alloc_from_tok(php_
 				 *
 				 * Original rfc2231 support by IceWarp Ltd. <[email protected]>
 				 */
+				currentencoded = 0;
 				check_name = strchr(name, '*');
 				if (check_name) {
 				  currentencoded = 1;
diff --git a/tests/rfc2231_plain_after_encoded.phpt b/tests/rfc2231_plain_after_encoded.phpt
new file mode 100644
index 0000000..72c8d1b
--- /dev/null
+++ b/tests/rfc2231_plain_after_encoded.phpt
@@ -0,0 +1,18 @@
+--TEST--
+A plain parameter following an RFC2231 (name*N) parameter is not leaked
+--SKIPIF--
+<?php if (!extension_loaded("mailparse")) print "skip"; ?>
+--FILE--
+<?php
+$m = mailparse_msg_create();
+mailparse_msg_parse($m, "Content-Type: x/y; a*0=\"foo\"; a*1=\"bar\"; b=\"baz\"\n\nbody\n");
+$d = mailparse_msg_get_part_data($m);
+var_dump($d['content-a']);
+var_dump($d['content-b']);
+mailparse_msg_free($m);
+echo "done\n";
+?>
+--EXPECT--
+string(6) "foobar"
+string(3) "baz"
+done