Commit 0a03d105939 for php.net

commit 0a03d10593956e9cba57571194763830d08bdbb7
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Tue May 12 17:40:10 2026 -0400

    ext/pcre: fix duplicate MARK key in matches array

    When a named capture group is also called "MARK" and the pattern uses
    the (*MARK:name) directive, populate_subpat_array() inserted two
    buckets with the same string key into the matches array.
    zend_hash_str_add_new skips the duplicate-key check, so the named
    capture's MARK and the directive's MARK both landed in the table.

    Switch to zend_hash_str_update so the directive's value overwrites
    the capture's value, restoring the behavior that existed via
    add_assoc_string_ex before d6cc31cf9538.

    Closes GH-22029

diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index b9f8e1211ff..6a62d9717e7 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -1079,7 +1079,7 @@ static void populate_subpat_array(
 	/* Add MARK, if available */
 	if (mark) {
 		ZVAL_STRING(&val, (char *)mark);
-		zend_hash_str_add_new(subpats_ht, ZEND_STRL("MARK"), &val);
+		zend_hash_str_update(subpats_ht, ZEND_STRL("MARK"), &val);
 	}
 }

diff --git a/ext/pcre/tests/mark_named_collision.phpt b/ext/pcre/tests/mark_named_collision.phpt
new file mode 100644
index 00000000000..b644c4d4402
--- /dev/null
+++ b/ext/pcre/tests/mark_named_collision.phpt
@@ -0,0 +1,15 @@
+--TEST--
+preg_match: (*MARK:name) directive does not collide with named group called MARK
+--FILE--
+<?php
+preg_match('/(?P<MARK>[abc])(*MARK:value)/', "abc", $m);
+echo "count: ", count($m), "\n";
+echo "MARK: ", $m['MARK'], "\n";
+echo "json: ", json_encode($m), "\n";
+echo "keys: ", implode(',', array_keys($m)), "\n";
+?>
+--EXPECT--
+count: 3
+MARK: value
+json: {"0":"a","MARK":"value","1":"a"}
+keys: 0,MARK,1