Skip to content

Commit 0a03d10

Browse files
committed
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 d6cc31c. Closes GH-22029
1 parent 48d588d commit 0a03d10

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

ext/pcre/php_pcre.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ static void populate_subpat_array(
10791079
/* Add MARK, if available */
10801080
if (mark) {
10811081
ZVAL_STRING(&val, (char *)mark);
1082-
zend_hash_str_add_new(subpats_ht, ZEND_STRL("MARK"), &val);
1082+
zend_hash_str_update(subpats_ht, ZEND_STRL("MARK"), &val);
10831083
}
10841084
}
10851085

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
preg_match: (*MARK:name) directive does not collide with named group called MARK
3+
--FILE--
4+
<?php
5+
preg_match('/(?P<MARK>[abc])(*MARK:value)/', "abc", $m);
6+
echo "count: ", count($m), "\n";
7+
echo "MARK: ", $m['MARK'], "\n";
8+
echo "json: ", json_encode($m), "\n";
9+
echo "keys: ", implode(',', array_keys($m)), "\n";
10+
?>
11+
--EXPECT--
12+
count: 3
13+
MARK: value
14+
json: {"0":"a","MARK":"value","1":"a"}
15+
keys: 0,MARK,1

0 commit comments

Comments
 (0)