From ce23b2cd3efe53751eaf6d593782cf998007d887 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:35:16 +0100 Subject: [PATCH] Fix GH-17139: Fix zip_entry_name() crash on invalid entry Don't increment the refcount, but latter remember the ID to check afterwards whether the resource still exists. Replaces GH-17142. --- ext/zip/php_zip.c | 3 ++- ext/zip/php_zip.h | 3 +++ ext/zip/tests/gh17319.phpt | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ext/zip/tests/gh17319.phpt diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 0c1dfaf5dd131..54bdffbecb03b 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1255,6 +1255,7 @@ PHP_FUNCTION(zip_read) RETURN_FALSE; } + zr_rsrc->zip_rsrc_handle = Z_RES_P(zip_dp)->handle; zr_rsrc->zf = zip_fopen_index(rsrc_int->za, rsrc_int->index_current, 0); if (zr_rsrc->zf) { rsrc_int->index_current++; @@ -1371,7 +1372,7 @@ static void php_zip_entry_get_info(INTERNAL_FUNCTION_PARAMETERS, int opt) /* {{{ RETURN_THROWS(); } - if (!zr_rsrc->zf) { + if (!zr_rsrc->zf || !zend_hash_index_exists(&EG(regular_list), zr_rsrc->zip_rsrc_handle)) { RETURN_FALSE; } diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 41392d1967d74..fea943cbbffce 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -60,6 +60,9 @@ typedef zip_rsrc * zip_rsrc_ptr; typedef struct _ze_zip_read_rsrc { struct zip_file *zf; struct zip_stat sb; + /* Used to check if the zip resource still exists, + * without holding a reference. This works because the IDs are unique. */ + zend_long zip_rsrc_handle; } zip_read_rsrc; /* Extends zend object */ diff --git a/ext/zip/tests/gh17319.phpt b/ext/zip/tests/gh17319.phpt new file mode 100644 index 0000000000000..04df39d839e7f --- /dev/null +++ b/ext/zip/tests/gh17319.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-17139 - zip_entry_name() crash +--EXTENSIONS-- +zip +--FILE-- + +--EXPECTF-- +Deprecated: Function zip_open() is deprecated in %s on line %d + +Deprecated: Function zip_read() is deprecated in %s on line %d + +Deprecated: Function zip_entry_name() is deprecated in %s on line %d +bool(false)