[php-src] master: Merge branch 'PHP-8.5'

Weilin Du <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Date: 2026-08-28T01:07:37+08:00

Commit: https://github.com/php/php-src/commit/0a40e06e69ba747a490ed6c9ecad535d458511ec
Raw diff: https://github.com/php/php-src/commit/0a40e06e69ba747a490ed6c9ecad535d458511ec.diff

Merge branch 'PHP-8.5'

* PHP-8.5:
  Merge branch 'PHP-8.4' into PHP-8.5

Changed paths:
  A  ext/phar/tests/gh23477.phpt
  M  NEWS
  M  ext/phar/phar.c


Diff:

diff --git a/NEWS b/NEWS
index 1323057cc07e..6ac1e8e329ac 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,8 @@ PHP                                                                        NEWS
 - Phar:
   . Fixed bug GH-23418 (Use-after-free when looking up mounted directories).
     (Weilin Du)
+  . Fixed bug GH-23477 (Memory leak on duplicate native Phar manifest entries).
+    (Weilin Du)
 
 - Standard:
   . Fixed an out-of-bounds read when following a redirect response with an
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index af3a4992d6d5..f64f27bac383 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -1227,7 +1227,10 @@ static zend_result phar_parse_pharfile(php_stream *fp, const char *fname, size_t
 		} else {
 			str = entry.filename;
 		}
-		zend_hash_add_mem(&mydata->manifest, str, (void*)&entry, sizeof(phar_entry_info));
+		if (!zend_hash_add_mem(&mydata->manifest, str, (void*)&entry, sizeof(phar_entry_info))) {
+			phar_metadata_tracker_free(&entry.metadata_tracker, entry.is_persistent);
+			zend_string_free(entry.filename);
+		}
 		if (mydata->is_persistent) {
 			zend_string_release(str);
 		}
diff --git a/ext/phar/tests/gh23477.phpt b/ext/phar/tests/gh23477.phpt
new file mode 100644
index 000000000000..cd015ddaa9b0
--- /dev/null
+++ b/ext/phar/tests/gh23477.phpt
@@ -0,0 +1,39 @@
+--TEST--
+GH-23477 (Memory leak on duplicate native Phar manifest entry)
+--EXTENSIONS--
+phar
+--INI--
+phar.require_hash=0
+--FILE--
+<?php
+$stub = "<?php __HALT_COMPILER(); ?>\r\n";
+
+function u32($value) {
+    return pack('V', $value);
+}
+
+function entry($name, $data, $metadata) {
+    $header = u32(strlen($name)) . $name
+        . u32(strlen($data)) . u32(0) . u32(strlen($data))
+        . u32(crc32($data)) . u32(0)
+        . u32(strlen($metadata)) . $metadata;
+    return [$header, $data];
+}
+
+$first = entry('a.txt', 'hello', 'i:1;');
+$second = entry('a.txt', 'world', 'i:2;');
+$manifest = u32(2) . "\x11\x00" . u32(0) . u32(0) . u32(0)
+    . $first[0] . $second[0];
+
+file_put_contents(__DIR__ . '/gh23477.phar',
+    $stub . u32(strlen($manifest)) . $manifest . $first[1] . $second[1]);
+
+$phar = new Phar(__DIR__ . '/gh23477.phar');
+echo iterator_count($phar), "\n";
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/gh23477.phar');
+?>
+--EXPECT--
+1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.