Skip to content

Commit 8fe20ce

Browse files
committed
ext/zip: Make ZipArchive non-serializable
A ZipArchive wraps a libzip resource that cannot survive serialization, so unserialize() silently produced a broken object (numFiles = 0) instead of erroring. Mark the class as not-serializable, consistent with Socket, CurlHandle and the Dba classes. Fixes GH-21682
1 parent 95b5b48 commit 8fe20ce

5 files changed

Lines changed: 22 additions & 3 deletions

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ PHP NEWS
266266
(kocsismate)
267267

268268
- Zip:
269+
. Fixed bug GH-21682 (ZipArchive must not be serializable).
270+
(Nickolay Harin)
269271
. Fixed ZipArchive callback being called after executor has shut down.
270272
(ilutov)
271273
. Support minimum version for libzip dependency updated to 1.0.0.

ext/standard/tests/strings/bug72434.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm
55
// The following array will be serialized and this representation will be freed later on.
66
$free_me = array(new StdClass());
77
// Create our payload and unserialize it.
8-
$serialized_payload = 'a:3:{i:1;N;i:2;O:10:"ZipArchive":1:{s:8:"filename";'.serialize($free_me).'}i:1;R:4;}';
8+
$serialized_payload = 'a:3:{i:1;N;i:2;O:8:"stdClass":1:{s:8:"filename";'.serialize($free_me).'}i:1;R:4;}';
99
$unserialized_payload = unserialize($serialized_payload);
1010
gc_collect_cycles();
1111
// The reference counter for $free_me is at -1 for PHP 7 right now.

ext/zip/php_zip.stub.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ function zip_entry_filesize($zip_entry): int|false {}
6464
#[\Deprecated(since: '8.0', message: 'use ZipArchive::statIndex() instead')]
6565
function zip_entry_compressionmethod($zip_entry): string|false {}
6666

67+
/**
68+
* @not-serializable
69+
*/
6770
class ZipArchive implements Countable
6871
{
6972
/**

ext/zip/php_zip_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/zip/tests/gh21682.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
GH-21682 (ZipArchive must not be serializable)
3+
--EXTENSIONS--
4+
zip
5+
--FILE--
6+
<?php
7+
try {
8+
serialize(new ZipArchive());
9+
} catch (\Exception $e) {
10+
echo $e->getMessage(), "\n";
11+
}
12+
?>
13+
--EXPECT--
14+
Serialization of 'ZipArchive' is not allowed

0 commit comments

Comments
 (0)