[PECL-CVS] [pecl-mail-mailparse] master: Fix memory leaks in mailparse_uudecode_all
[email protected] (Ilia Alshanetsky via Remi Collet) Wed, 24 Jun 2026 08:15:46 +0000
| Newsgroups | php.pecl.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Committer: Remi Collet (remicollet)
Date: 2026-06-24T10:14:27+02:00
Commit: https://github.com/php/pecl-mail-mailparse/commit/5e5778a72fb9ea8a89a0457aacce6271c80f9e5b
Raw diff: https://github.com/php/pecl-mail-mailparse/commit/5e5778a72fb9ea8a89a0457aacce6271c80f9e5b.diff
Fix memory leaks in mailparse_uudecode_all
Changed paths:
A tests/uudecode_all_no_begin.phpt
M mailparse.c
Diff:
diff --git a/mailparse.c b/mailparse.c
index 6210be0..b6f973b 100644
--- a/mailparse.c
+++ b/mailparse.c
@@ -794,7 +794,7 @@ PHP_FUNCTION(mailparse_uudecode_all)
{
zval *file, item;
char *buffer = NULL;
- zend_string *outpath;
+ zend_string *outpath, *partpath = NULL;
int nparts = 0;
php_stream *instream, *outstream = NULL, *partstream = NULL;
@@ -839,6 +839,7 @@ PHP_FUNCTION(mailparse_uudecode_all)
add_assoc_string(&item, "filename", ZSTR_VAL(outpath));
add_next_index_zval(return_value, &item);
zend_string_release(outpath);
+ outpath = NULL;
}
/* add an item */
@@ -846,16 +847,19 @@ PHP_FUNCTION(mailparse_uudecode_all)
add_assoc_string(&item, "origfilename", origfilename);
/* create a temp file for the data */
- partstream = _mailparse_create_stream(&outpath);
+ partstream = _mailparse_create_stream(&partpath);
if (partstream) {
nparts++;
- add_assoc_string(&item, "filename", ZSTR_VAL(outpath));
+ add_assoc_string(&item, "filename", ZSTR_VAL(partpath));
add_next_index_zval(return_value, &item);
/* decode it */
mailparse_do_uudecode(instream, partstream);
php_stream_close(partstream);
- zend_string_release(outpath);
+ zend_string_release(partpath);
+ } else {
+ /* temp-file creation failed: drop the half-built item */
+ zval_ptr_dtor(&item);
}
} else {
/* write to the output file */
@@ -867,7 +871,14 @@ PHP_FUNCTION(mailparse_uudecode_all)
efree(buffer);
if (nparts == 0) {
- /* delete temporary file */
+ /* no uuencoded part decoded: release the unused initial temp-file
+ * path, or discard the partially-built array if a begin line was seen
+ * but every part failed to decode */
+ if (outpath) {
+ zend_string_release(outpath);
+ } else {
+ zval_ptr_dtor(return_value);
+ }
RETURN_FALSE;
}
}
diff --git a/tests/uudecode_all_no_begin.phpt b/tests/uudecode_all_no_begin.phpt
new file mode 100644
index 0000000..94520f4
--- /dev/null
+++ b/tests/uudecode_all_no_begin.phpt
@@ -0,0 +1,17 @@
+--TEST--
+mailparse_uudecode_all on input without a "begin" line does not leak
+--SKIPIF--
+<?php if (!extension_loaded("mailparse")) print "skip"; ?>
+--FILE--
+<?php
+/* With no "begin" line the temp-file path string was never released. */
+$fp = fopen("php://memory", "r+");
+fwrite($fp, "plain text\nno uuencoded data here\n");
+rewind($fp);
+var_dump(mailparse_uudecode_all($fp));
+fclose($fp);
+echo "done\n";
+?>
+--EXPECT--
+bool(false)
+done