php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80833 ZipArchive::getStream doesn't use setPassword
Submitted: 2021-03-05 04:31 UTC Modified: 2021-03-30 13:00 UTC
From: admin at lithi dot io Assigned:
Status: Verified Package: zip (PECL)
PHP Version: 7.4 OS: Ubuntu 20.04 LTS
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2021-03-05 04:31 UTC] admin at lithi dot io
Description:
------------
I try to read the content of a ZIP archive entry with ZipArchive::getStream to put its content into a variable with fread().

The archive is protected by a password (EM_AES_256).

getStream() doesn't use setPassword() to provide a stream.

getStream() from a non-password protected archive works.
extractTo() from a password protected archive works.

Thanks.

Test script:
---------------
<?php
$create_zip = new ZipArchive();
$create_zip->open("test.zip", ZipArchive::CREATE);
$create_zip->setPassword("password");
$create_zip->addFromString("test.txt", "This is a test string.");
$create_zip->setEncryptionName("test.txt", ZipArchive::EM_AES_256);
$create_zip->close();

$extract_zip = new ZipArchive();
$extract_zip->open("test.zip", ZipArchive::RDONLY);
$extract_zip->setPassword("password");
$file_stream = $extract_zip->getStream("test.txt");
if (is_resource($file_stream)) {
    echo "OK".PHP_EOL;
} else {
    echo "NOT OK".PHP_EOL;
}
unlink("test.zip");
fclose($file_stream);
$extract_zip->close();

Expected result:
----------------
OK

Actual result:
--------------
NOT OK

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-03-05 04:34 UTC] admin at lithi dot io
Possibly a regression from #71665?
 [2021-03-05 10:49 UTC] cmb@php.net
-Status: Open +Status: Verified -PHP Version: 8.0.3 +PHP Version: 7.4 -Assigned To: +Assigned To: cmb
 [2021-03-05 10:49 UTC] cmb@php.net
Indeed, at least PHP 7.4 is affected by this as well.  The problem
is that we're internally open the archive again[1], but don't set
the password.

[1] <https://github.com/php/php-src/blob/php-7.4.16/ext/zip/zip_stream.c#L231>
 [2021-03-05 13:13 UTC] cmb@php.net
I am afraid this can't be fixed for any stable PHP version, due
to an inevitable ABI break.

The basic problem is that libzip offers no public API to get an
already set password, and struct zip is private.  Therefore we
would need to store the password in the ZipArchive object (i.e. in
ze_zip_object), but extending the existing struct would be an ABI
break, because putting the new member at the end of the struct
would not work since zend_object has variable size, and putting it
before the zend_object would break the offsetof retrieval.

Thus, the only way to allow to retrieve password protected files
as streams would be to add an additional optional $password
parameter to ::getStream(), which is a new feature, but may still
be covered by the self-contained feature exemption.

I should also point out that bug #71665 never had been fixed wrt.
::getStream(); this likely has been confused with the general
support for encrypted archives in PHP 7.2.0.
 [2021-03-05 13:29 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #80833: ZipArchive::getStream doesn't use setPassword
On GitHub:  https://github.com/php/php-src/pull/6752
Patch:      https://github.com/php/php-src/pull/6752.patch
 [2021-03-30 13:00 UTC] cmb@php.net
-Assigned To: cmb +Assigned To:
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Mon Apr 19 16:01:26 2021 UTC