From 57918b1a1bd0d74a1224e630bae25644ddb89234 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 7 May 2021 18:18:06 +0200 Subject: [PATCH] Fix #80863: ZipArchive::extractTo() ignores references We need to cater to references, when traversing the files to extract. While we're at it, we move the `zval_file` declaration into a narrower scope. Closes GH-6959. --- NEWS | 3 +++ ext/zip/php_zip.c | 4 ++-- ext/zip/tests/bug80863.phpt | 43 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 ext/zip/tests/bug80863.phpt diff --git a/NEWS b/NEWS index a5d9a356d32..0b4e25645b9 100644 --- a/NEWS +++ b/NEWS @@ -40,6 +40,9 @@ PHP NEWS - XMLReader: . Fixed bug #73246 (XMLReader: encoding length not checked). (cmb) +- Zip: + . Fixed bug #80863 (ZipArchive::extractTo() ignores references). (cmb) + 06 May 2021, PHP 7.4.19 - PDO_pgsql: diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 21182068d1d..2a2577de225 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -2616,7 +2616,6 @@ static ZIPARCHIVE_METHOD(extractTo) zval *self = ZEND_THIS; zval *zval_files = NULL; - zval *zval_file = NULL; php_stream_statbuf ssb; char *pathto; size_t pathto_len; @@ -2653,7 +2652,8 @@ static ZIPARCHIVE_METHOD(extractTo) RETURN_FALSE; } for (i = 0; i < nelems; i++) { - if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), i)) != NULL) { + zval *zval_file; + if ((zval_file = zend_hash_index_find_deref(Z_ARRVAL_P(zval_files), i)) != NULL) { switch (Z_TYPE_P(zval_file)) { case IS_LONG: break; diff --git a/ext/zip/tests/bug80863.phpt b/ext/zip/tests/bug80863.phpt new file mode 100644 index 00000000000..9b9d3b2ff39 --- /dev/null +++ b/ext/zip/tests/bug80863.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #80863 (ZipArchive::extractTo() ignores references) +--SKIPIF-- + +--FILE-- +open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE); +$zip->addFromString("file1.txt", "contents"); +$zip->addFromString("file2.txt", "contents"); +$zip->close(); + +$target = __DIR__ . "/bug80683"; +mkdir($target); + +$files = [ + "file1.txt", + "file2.txt", +]; +// turn into references +foreach ($files as &$file); + +$zip = new ZipArchive(); +$zip->open($archive); +$zip->extractTo($target, $files); +var_dump(is_file("$target/file1.txt")); +var_dump(is_file("$target/file2.txt")); +?> +--EXPECT-- +bool(true) +bool(true) +--CLEAN-- +