Commit 985b66bb672 for php
commit 985b66bb6723a7191ae0bbc5cb94a0eb0654d3af
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Thu Oct 22 07:34:23 2026 -0400
Fix GH-24531: Crash when flushing a renamed zip-based phar
When phar->fp is not open, phar_zip_flush() reopens the archive by name,
and if the file was renamed or removed the stream holding the original
contents is NULL. phar_zip_changed_apply_int() already skipped the seek on
a NULL stream but still copied unmodified entries from it. Fail the flush
with the existing copy error instead, as tar and native phar archives
already do. Directories and empty entries need no original data and still
flush.
Fixes GH-24531
Closes GH-24535
diff --git a/NEWS b/NEWS
index b2d2ef47260..d23571a751f 100644
--- a/NEWS
+++ b/NEWS
@@ -249,6 +249,8 @@ PHP NEWS
are equal). (Lazizbek Ergashev)
. Fixed bug GH-25092 (Double free in Phar::copy() on link and
mounted entries). (Lazizbek Ergashev)
+ . Fixed bug GH-24531 (Crash when modifying a zip-based phar whose file was
+ renamed). (Ilia Alshanetsky)
- Phpdbg:
. Fix wrong command names. (ndossche, Weilin Du)
diff --git a/ext/phar/tests/zip/gh24531.phpt b/ext/phar/tests/zip/gh24531.phpt
new file mode 100644
index 00000000000..44f9e173606
--- /dev/null
+++ b/ext/phar/tests/zip/gh24531.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-24531 (NULL pointer dereference when flushing a zip-based phar whose file was renamed)
+--EXTENSIONS--
+phar
+--INI--
+phar.readonly=0
+phar.require_hash=0
+--FILE--
+<?php
+$source = __DIR__ . '/gh24531.phar.zip';
+$target = __DIR__ . '/gh24531-renamed.phar.zip';
+
+$phar = new Phar($source);
+$phar->addFromString('first', 'first');
+unset($phar);
+
+rename($source, $target);
+
+try {
+ $phar = new Phar($source);
+ $phar->addFromString('second', 'second');
+} catch (PharException $e) {
+ echo $e::class, ": ", $e->getMessage(), PHP_EOL;
+}
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/gh24531.phar.zip');
+@unlink(__DIR__ . '/gh24531-renamed.phar.zip');
+?>
+--EXPECTF--
+PharException: phar zip flush of "%sgh24531.phar.zip" failed: unable to copy contents of file "first" while creating zip-based phar "%sgh24531.phar.zip"
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
index c1230cb7807..fc95bd71b0f 100644
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -1154,7 +1154,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
}
}
- if (!entry->is_dir && entry->compressed_filesize && SUCCESS != php_stream_copy_to_stream_ex(p->old, p->filefp, entry->compressed_filesize, NULL)) {
+ if (!entry->is_dir && entry->compressed_filesize && (!p->old || SUCCESS != php_stream_copy_to_stream_ex(p->old, p->filefp, entry->compressed_filesize, NULL))) {
spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
return ZEND_HASH_APPLY_STOP;
}