From a9eeac22d42bd33dc475c0f40065cb953f64d4a2 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Thu, 26 Mar 2026 13:33:20 -0400 Subject: [PATCH] Fix GH-17399: iconv memory leak with large line-length Move the buf allocation in _php_iconv_mime_encode() before the iconv_open() calls. When max_line_len is excessively large (e.g. PHP_INT_MAX), safe_emalloc triggers an OOM bailout that skips cleanup, leaking the iconv handles allocated via system malloc. By allocating buf first, a bailout happens before any iconv handles exist. Closes GH-17399 --- ext/iconv/iconv.c | 4 ++-- ext/iconv/tests/gh17399.phpt | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 ext/iconv/tests/gh17399.phpt diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 13dc7074b9b3..b749907dc3e1 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -942,6 +942,8 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn goto out; } + buf = safe_emalloc(1, max_line_len, 5); + cd_pl = iconv_open(ICONV_ASCII_ENCODING, enc); if (cd_pl == (iconv_t)(-1)) { if (errno == EINVAL) { @@ -962,8 +964,6 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn goto out; } - buf = safe_emalloc(1, max_line_len, 5); - char_cnt = max_line_len; _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); diff --git a/ext/iconv/tests/gh17399.phpt b/ext/iconv/tests/gh17399.phpt new file mode 100644 index 000000000000..078bfe2c39ce --- /dev/null +++ b/ext/iconv/tests/gh17399.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv memory leak with large line-length in iconv_mime_encode) +--EXTENSIONS-- +iconv +--FILE-- + PHP_INT_MAX, +); +iconv_mime_encode('Subject', 'test', $options); +?> +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d