[php-src] PHP-8.4: Fix GH-23477: Memory leak on duplicate native Phar manifest entries (#23479)

Weilin Du via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Committer: GitHub (web-flow)
Pusher: LamentXU123
Date: 2026-08-28T01:03:13+08:00

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

Fix GH-23477: Memory leak on duplicate native Phar manifest entries (#23479)

Check the insertion result and release these allocations on failure.

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


Diff:

diff --git a/NEWS b/NEWS
index 1a9f52b2ab91..31021de07015 100644
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,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 7e74de782ccb..fc21692db2c1 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -1234,7 +1234,10 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname
 		} else {
 			str = zend_string_init(entry.filename, entry.filename_len, 0);
 		}
-		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);
+			pefree(entry.filename, entry.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.