Skip to content

Commit 04c41f0

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: ext/zip: ZipArchive::extractTo() ignores files given in a non-list array # Conflicts: # ext/zip/php_zip.c
2 parents e79d7e5 + 7184093 commit 04c41f0

2 files changed

Lines changed: 49 additions & 12 deletions

File tree

‎ext/zip/php_zip.c‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2920,7 +2920,7 @@ PHP_METHOD(ZipArchive, extractTo)
29202920
}
29212921
}
29222922

2923-
uint32_t nelems, i;
2923+
uint32_t nelems;
29242924
ZIP_FROM_OBJECT(intern, self);
29252925

29262926
if (files_str) {
@@ -2932,19 +2932,18 @@ PHP_METHOD(ZipArchive, extractTo)
29322932
if (nelems == 0 ) {
29332933
RETURN_FALSE;
29342934
}
2935-
for (i = 0; i < nelems; i++) {
2936-
zval *zval_file;
2937-
if ((zval_file = zend_hash_index_find_deref(files_ht, i)) != NULL) {
2938-
if (Z_TYPE_P(zval_file) == IS_STRING) {
2939-
if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), -1)) {
2940-
RETURN_FALSE;
2941-
}
2942-
} else {
2943-
zend_argument_type_error(2, "must only have elements of type string, %s given", zend_zval_value_name(zval_file));
2944-
RETURN_THROWS();
2935+
zval *zval_file;
2936+
ZEND_HASH_FOREACH_VAL(files_ht, zval_file) {
2937+
ZVAL_DEREF(zval_file);
2938+
if (Z_TYPE_P(zval_file) == IS_STRING) {
2939+
if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), -1)) {
2940+
RETURN_FALSE;
29452941
}
2942+
} else {
2943+
zend_argument_type_error(2, "must only have elements of type string, %s given", zend_zval_value_name(zval_file));
2944+
RETURN_THROWS();
29462945
}
2947-
}
2946+
} ZEND_HASH_FOREACH_END();
29482947
} else {
29492948
/* Extract all files */
29502949
zip_int64_t i, filecount = zip_get_num_entries(intern, 0);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
ZipArchive::extractTo() with a non-list files array (non-sequential keys)
3+
--EXTENSIONS--
4+
zip
5+
--FILE--
6+
<?php
7+
$archive = __DIR__ . "/oo_extract_array_keys.zip";
8+
9+
$zip = new ZipArchive();
10+
$zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
11+
$zip->addFromString("file0.txt", "zero");
12+
$zip->addFromString("file1.txt", "one");
13+
$zip->close();
14+
15+
$target = __DIR__ . "/oo_extract_array_keys";
16+
mkdir($target);
17+
18+
// array_filter() (and array_unique/array_diff) preserve keys, so this is [1 => "file1.txt"],
19+
// a perfectly valid list of entry names that is not a packed 0-based array.
20+
$files = array_filter(["file0.txt", "file1.txt"], fn($f) => $f === "file1.txt");
21+
22+
$zip = new ZipArchive();
23+
$zip->open($archive);
24+
var_dump($zip->extractTo($target, $files));
25+
$zip->close();
26+
27+
var_dump(is_file("$target/file1.txt"));
28+
?>
29+
--EXPECT--
30+
bool(true)
31+
bool(true)
32+
--CLEAN--
33+
<?php
34+
@unlink(__DIR__ . "/oo_extract_array_keys.zip");
35+
$target = __DIR__ . "/oo_extract_array_keys";
36+
@unlink("$target/file1.txt");
37+
@rmdir($target);
38+
?>

0 commit comments

Comments
 (0)