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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: andrew at nicols dot co dot uk
New email:
PHP Version: OS:

 

 [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

Pull Requests

Pull requests:

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-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 14:01:29 2024 UTC