Bug #80863 [NEW]: extractTo sometimes does not extract anything
| From: | lars at larsegon dot se | Date: | Sun, 14 Mar 2021 13:45:36 +0000 |
| Subject: | Bug #80863 [NEW]: extractTo sometimes does not extract anything | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-232705@lists.php.net to get a copy of this message | ||
From: lars at larsegon dot se
Operating system: Linux
PHP version: 8.0.3
Package: Zip Related
Bug Type: Bug
Bug description:extractTo sometimes does not extract anything
Description:
------------
Two strictly equal arrays are treated differently by
ZipArchive::extractTo().
In the attached script I'm creating a zip archive, and then extracting
the files in the zip file again.
To extract the files, I'm calling ZipArchive::extractTo(targetPath,
files), where files is a hard-coded array of paths to the files in the
zip archive.
The script also has a couple of functions, one which turns a list of
paths into a tree (list2tree) and one which turns the tree back into a
list of paths (tree2list). If output = tree2list(list2tree(input)),
output will be strictly equal to input, as can be seen in the asserting
if-clause in the script.
Even though output === input, ZipArchive::extractTo(targetPath, output)
extracts nothing, and ZipArchive::extractTo(targetPath, input) extracts
everything.
Test script:
---------------
<?php
function list2tree(array $paths): array
{
$tree = [];
foreach ($paths as $path) {
$parts = explode("/", $path);
$node = &$tree;
foreach ($parts as $pathSegment) {
if (empty($pathSegment) && $node !== $tree) {
continue;
}
if (is_string($node)) {
throw new \RuntimeException("Name collision");
}
$node = &$node[$pathSegment];
}
$node = '';
}
return $tree;
}
function tree2list(array $tree): array
{
$list = [];
foreach ($tree as $name => $content) {
if (is_array($content)) {
$subList = tree2list($content);
foreach ($subList as &$node) {
$node = "$name/$node";
}
$list = array_merge($list, $subList);
} else {
$list[] = $name;
}
}
return $list;
}
function createArchive()
{
$archive = tempnam(sys_get_temp_dir(), "phpzip");
$zip = new ZipArchive;
$zip->open($archive, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFromString("dir/file.txt", "contents");
$zip->addFromString("dir/file2.txt", "contents");
$zip->close();
return $archive;
}
$files = [
"dir/file.txt",
"dir/file2.txt",
];
$archive = createArchive();
// Calling these functions is what corrupts the file list.
$tree = list2tree($files);
$extract = tree2list($tree);
// But we can assert that $extract and $files are strictly equal
if ($extract !== $files) {
throw new \LogicException();
}
$target = tempnam(sys_get_temp_dir(), "phpzip");
unlink($target);
mkdir($target);
$e = new ZipArchive;
$e->open($archive);
// Even though $extract and $files are strictly equal,
// the following line extracts nothing:
$e->extractTo($target, $extract);
// But the following line extracts all files (if you uncomment it):
// $e->extractTo($target, $files);
var_dump($extract);
echo
ls -lah "$target";
Expected result:
----------------
I expect two strictly equal arrays of zip-entries to extract the same
set of files from the zip archive.
Actual result:
--------------
ZipArchive::extractTo() extracts none of the files in the second
argument, despite them being a list of files in the archive.
--
Edit bug report at https://bugs.php.net/bug.php?id=80863&edit=1
--
Fix committed: https://bugs.php.net/fix.php?id=80863&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=80863&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=80863&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=80863&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=80863&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=80863&r=support
Expected behavior: https://bugs.php.net/fix.php?id=80863&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=80863&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=80863&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=80863&r=globals
PHP version support discontinued: https://bugs.php.net/fix.php?id=80863&r=phptooold
Daylight Savings: https://bugs.php.net/fix.php?id=80863&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=80863&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=80863&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=80863&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=80863&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=80863&r=mysqlcfg