[pecl-mail-mailparse] master: Fix arg zval leak in extract_callback_user_func
| From: | Ilia Alshanetsky via Remi Collet | Date: | Fri, 12 Jun 2026 13:40:02 +0000 |
| Subject: | [pecl-mail-mailparse] master: Fix arg zval leak in extract_callback_user_func | ||
| Groups: | php.pecl.cvs | ||
| Request: | Send a blank email to pecl-cvs+get-28573@lists.php.net to get a copy of this message | ||
Author: Ilia Alshanetsky (iliaal)
Committer: Remi Collet (remicollet)
Date: 2026-06-12T15:39:47+02:00
Commit: https://github.com/php/pecl-mail-mailparse/commit/696d40f8691b3b8d2a36f17eeedba65aa98d9f48
Raw diff: https://github.com/php/pecl-mail-mailparse/commit/696d40f8691b3b8d2a36f17eeedba65aa98d9f48.diff
Fix arg zval leak in extract_callback_user_func
The callback ZVAL_STRINGL's the chunk into
arg but only released it on
the success path. Both early returns — when zend_fcall_info_init() fails
and when zend_call_function() fails — returned without dtoring arg,
leaking one zend_string per chunk. The init-failure path is reachable
from userland by passing a non-callable as the extract callback.
zend_fcall_info_argn() ZVAL_COPYs the argument into fci.params (its own
ref), so the original arg always needs exactly one zval_ptr_dtor.
Release it on every path; dtor retval only on success, where the
engine has actually written it.
Changed paths:
M mailparse.c
Diff:
diff --git a/mailparse.c b/mailparse.c
index 7d8d218..25553f3 100644
--- a/mailparse.c
+++ b/mailparse.c
@@ -1206,19 +1206,19 @@ static int extract_callback_user_func(php_mimepart *part, zval *userfunc,
const
if (zend_fcall_info_init(userfunc, 0, &fci, &fcc, NULL, NULL) == FAILURE) {
zend_error(E_WARNING, "%s(): unable to call user function",
get_active_function_name());
+ zval_ptr_dtor(&arg);
return 0;
}
zend_fcall_info_argn(&fci, 1, &arg);
fci.retval = &retval;
- if (zend_call_function(&fci, &fcc)) {
- zend_fcall_info_args_clear(&fci, 1);
+ if (zend_call_function(&fci, &fcc) == SUCCESS) {
+ zval_ptr_dtor(&retval);
+ } else {
zend_error(E_WARNING, "%s(): unable to call user function",
get_active_function_name());
- return 0;
}
zend_fcall_info_args_clear(&fci, 1);
- zval_ptr_dtor(&retval);
zval_ptr_dtor(&arg);
return 0;