|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80863 ZipArchive::extractTo() ignores references
Submitted: 2021-03-14 13:45 UTC Modified: 2021-05-07 15:54 UTC
From: lars at larsegon dot se Assigned: cmb (profile)
Status: Closed Package: Zip Related
PHP Version: 7.4 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
Solve the problem:
24 - 6 = ?
Subscribe to this entry?

 [2021-03-14 13:45 UTC] lars at larsegon dot se
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:

function list2tree(array $paths): array
    $tree = [];
    foreach ($paths as $path) {
        $parts = explode("/", $path);
        $node  = &$tree;
        foreach ($parts as $pathSegment) {
            if (empty($pathSegment) && $node !== $tree) {

            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");

    return $archive;

$files = [

$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");

$e = new ZipArchive;

// 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);


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.


Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2021-05-07 14:13 UTC]
-Status: Open +Status: Verified -PHP Version: 8.0.3 +PHP Version: 7.4 -Assigned To: +Assigned To: cmb
 [2021-05-07 14:13 UTC]
That's an issue with references.  Thanks for reporting!
 [2021-05-07 15:54 UTC]
-Summary: extractTo sometimes does not extract anything +Summary: ZipArchive::extractTo() ignores references
 [2021-05-07 15:55 UTC]
The following pull request has been associated:

Patch Name: Fix #80863: ZipArchive::extractTo() ignores references
On GitHub:
 [2021-05-07 17:23 UTC]
Automatic comment on behalf of cmb69
Log: Fix #80863: ZipArchive::extractTo() ignores references
 [2021-05-07 17:23 UTC]
-Status: Verified +Status: Closed
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Apr 15 19:01:28 2024 UTC