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;
 		}