From 10f18b48db3fbdea2c9d7d85a797916af3d6a6bd Mon Sep 17 00:00:00 2001 From: lazerg Date: Tue, 10 Nov 2026 13:11:19 +0500 Subject: [PATCH 1/2] Fix GH-25360: ZipArchive assertion when error handler throws at shutdown --- ext/zip/php_zip.c | 7 ++++++- ext/zip/tests/gh25360.phpt | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ext/zip/tests/gh25360.phpt diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 5baecfc18933..4d1b2c4e1843 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1184,7 +1184,12 @@ bool php_zip_archive_release(php_zip_archive *archive) int err = zip_close(archive->za); if (err != 0) { if (!archive->bailout_callback) { - php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(archive->za)); + /* An error handler that throws during shutdown bails out. */ + zend_try { + php_error_docref(NULL, E_WARNING, "Cannot destroy the zip context: %s", zip_strerror(archive->za)); + } zend_catch { + archive->bailout_callback = true; + } zend_end_try(); } zip_discard(archive->za); } diff --git a/ext/zip/tests/gh25360.phpt b/ext/zip/tests/gh25360.phpt new file mode 100644 index 000000000000..51b297251ece --- /dev/null +++ b/ext/zip/tests/gh25360.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-25360 (Assertion failure when the error handler throws on the implicit close at shutdown) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +zip +--FILE-- +open(__DIR__ . '/gh25360.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE); +file_put_contents(__DIR__ . '/gh25360.txt', 'contents'); +$zip->addFile(__DIR__ . '/gh25360.txt', 'file.txt'); +unlink(__DIR__ . '/gh25360.txt'); +set_error_handler(function () { + throw new Exception('handler'); +}); +echo "Done\n"; +?> +--CLEAN-- + +--EXPECTF-- +Done + +Fatal error: Uncaught Exception: handler in %s:%d +Stack trace: +#0 [internal function]: {closure:%s:%d}(2, '%s', 'Unknown', 0) +#1 {main} + thrown in %s on line %d From e40a5e8e4935d80e94d8651629a5cf57528432ff Mon Sep 17 00:00:00 2001 From: lazerg Date: Tue, 10 Nov 2026 13:16:02 +0500 Subject: [PATCH 2/2] Also guard the close warning in php_zipobj_close() --- ext/zip/php_zip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 4d1b2c4e1843..14ee1bf3b822 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -660,7 +660,11 @@ static bool php_zipobj_close(ze_zip_object *obj, zend_string **out_str) /* {{{ * archive->close = true; int err = zip_close(intern); if (err) { - php_error_docref(NULL, E_WARNING, "%s", zip_strerror(intern)); + zend_try { + php_error_docref(NULL, E_WARNING, "%s", zip_strerror(intern)); + } zend_catch { + archive->bailout_callback = true; + } zend_end_try(); /* Save error for property reader */ zip_error_t *ziperr = zip_get_error(intern); obj->err_zip = zip_error_code_zip(ziperr);