From eab209d81d1a8237a033d5981c5cc2f23b108e0d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:33:41 +0100 Subject: [PATCH] Fix GH-17518: offset overflow phar extractTo() `search` can be the empty string, so we need to check the length before checking the last char. Closes GH-17519. --- NEWS | 3 +++ ext/phar/phar_object.c | 2 +- ext/phar/tests/gh17518.phpt | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ext/phar/tests/gh17518.phpt diff --git a/NEWS b/NEWS index a7db6d9f3002d..1ca375ce8bae3 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,9 @@ PHP NEWS - Opcache: . Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos) +- Phar: + . Fixed bug GH-17518 (offset overflow phar extractTo()). (nielsdos) + - PHPDBG: . Fix crashes in function registration + test. (nielsdos, Girgias) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 98efcf701c6c4..39526ce4b235b 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -4306,7 +4306,7 @@ static int extract_helper(phar_archive_data *archive, zend_string *search, char if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1; extracted++; } ZEND_HASH_FOREACH_END(); - } else if ('/' == ZSTR_VAL(search)[ZSTR_LEN(search) - 1]) { + } else if (ZSTR_LEN(search) > 0 && '/' == ZSTR_VAL(search)[ZSTR_LEN(search) - 1]) { /* ends in "/" -- extract all entries having that prefix */ ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) { if (0 != strncmp(ZSTR_VAL(search), entry->filename, ZSTR_LEN(search))) continue; diff --git a/ext/phar/tests/gh17518.phpt b/ext/phar/tests/gh17518.phpt new file mode 100644 index 0000000000000..6a45e390edd0a --- /dev/null +++ b/ext/phar/tests/gh17518.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-17518 (offset overflow phar extractTo()) +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +extractTo(__DIR__ . '/gh17518', ''); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--CLEAN-- + +--EXPECTF-- +PharException: phar error: attempted to extract non-existent file or directory "" from phar "%sgh17518.phar.php"