php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80261 Files over MAX_PATH are accepted but lead to an Error on close()
Submitted: 2020-10-20 05:00 UTC Modified: 2020-10-29 13:44 UTC
From: andrew at nicols dot co dot uk Assigned: cmb (profile)
Status: Closed Package: Zip Related
PHP Version: 7.4.11 OS: Windows
Private report: No CVE-ID: None
 [2020-10-20 05:00 UTC] andrew at nicols dot co dot uk
Description:
------------
When calling `addFile()` where the input `$filename` argument is a path whose length is over MAX_PATH chars, the `ZipArchive::addFile()` function does not emit any warning, but `ZipArchive::close()` fails.

The file can still be accessed by the script via calls like `file_get_contents()`, but ZipArchive is unable to do so.

On newer systems (Windows 10) the MAX_PATH applies to the folder containing the path.
On older systems it appears that MAX_PATH applies to the full filename.

Documentation on MAX_PATH is available at: https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation

Ideally one or more of the following should happen:
- ZipArchive should use one of the known methods for working with files whose filename is over MAX_PATH
- A warning should be displayed when calling `ZipArchive::addFile()`
- More information should be added to the error on `ZipArchive::close()` to identify the specific file causing the issue

Test script:
---------------
<?php
ini_set('zend.assertions', 1);

$finaldir = str_pad(sys_get_temp_dir() . '/', 261, 'x');
@mkdir($finaldir, 0777, true);
$contentfile = "{$finaldir}/example_input.txt";
@unlink($contentfile);

$content = "Some example content";
file_put_contents($contentfile, $content);
assert(file_get_contents($contentfile) === $content, "Unable to read back the content");

$za = new ZipArchive();
$result = $za->open(__DIR__ . '/export.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
assert($result, "Unable to open ZipArchive");

$result = $za->addFile($contentfile);
assert($result, "Unable to call addFile({$contentfile})");

$result = $za->close();
assert($result, "Unable to call close()");

Expected result:
----------------
No output

Actual result:
--------------
PHP Warning:  ZipArchive::close(): Read error: No such file or directory in C:\Users\travis\build\andrewnicols\fun\maxlength.php on line 19
PHP Warning:  assert(): Unable to call close() failed in C:\Users\travis\build\andrewnicols\fun\maxlength.php on line 20

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-10-20 09:48 UTC] cmb@php.net
-Status: Open +Status: Analyzed -Assigned To: +Assigned To: cmb
 [2020-10-20 09:48 UTC] cmb@php.net
This is primarily an libzip upstream issue, which mostly resolved
as of libzip 1.7.0, but the official Windows PHP 7 build currently
use libzip 1.5.1, where the reported behavior occurs.

With libzip 1.7.1 (currently used for PHP 8.0 prerelease builds),
::addFile() fails (returns false), but ::getStatusString() returns
the unhelpful "Read error: Unknown error", which is an upstream
issue that is not resolved in their "master" branch yet. I'll
submit a respective PR, so that you'd get "Read error: No such
file or directory".

While debugging this I also tried to use the respective UNC file
name for ::addFile(), and that failed with "No error" because
ext/zip does not explicitly report PHP related errors (in this
case failing expand_filepath()).  That might be regarded a
separate issue, though.

Long story short: we should update to libzip 1.7.1 for PHP 7.4.13,
and maybe for PHP 7.3.25.
 [2020-10-20 09:57 UTC] cmb@php.net
> I'll submit a respective PR, […]

<https://github.com/nih-at/libzip/pull/216>
 [2020-10-20 10:43 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Raise E_WARNING on PHP related errors
On GitHub:  https://github.com/php/php-src/pull/6356
Patch:      https://github.com/php/php-src/pull/6356.patch
 [2020-10-28 09:41 UTC] cmb@php.net
The php-src PR and the upstream PR have been merged; waiting on
7.4.12 to be released to roll out the update to libzip 1.7.1.
 [2020-10-29 13:44 UTC] cmb@php.net
-Status: Analyzed +Status: Closed
 [2020-10-29 13:44 UTC] cmb@php.net
libzip 1.7.1 has been rolled out to PHP 7.4 staging.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Nov 29 14:01:24 2020 UTC