mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fixed bug #79257
Replace an existing entry for a given name only if we have a match.
This commit is contained in:
parent
93b183ed55
commit
3a51530963
2
NEWS
2
NEWS
@ -21,6 +21,8 @@ PHP NEWS
|
||||
. Fixed bug #79188 (Memory corruption in preg_replace/preg_replace_callback
|
||||
and unicode). (Nikita)
|
||||
. Fixed bug #79241 (Segmentation fault on preg_match()). (Nikita)
|
||||
. Fixed bug #79257 (Duplicate named groups (?J) prefer last alternative even
|
||||
if not matched). (Nikita)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #79254 (getenv() w/o arguments not showing changes). (cmb)
|
||||
|
@ -995,6 +995,20 @@ static inline void populate_match_value(
|
||||
}
|
||||
}
|
||||
|
||||
static inline void add_named(
|
||||
zval *subpats, zend_string *name, zval *val, zend_bool unmatched) {
|
||||
/* If the DUPNAMES option is used, multiple subpatterns might have the same name.
|
||||
* In this case we want to preserve the one that actually has a value. */
|
||||
if (!unmatched) {
|
||||
zend_hash_update(Z_ARRVAL_P(subpats), name, val);
|
||||
} else {
|
||||
if (!zend_hash_add(Z_ARRVAL_P(subpats), name, val)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Z_TRY_ADDREF_P(val);
|
||||
}
|
||||
|
||||
/* {{{ add_offset_pair */
|
||||
static inline void add_offset_pair(
|
||||
zval *result, const char *subject, PCRE2_SIZE start_offset, PCRE2_SIZE end_offset,
|
||||
@ -1023,8 +1037,7 @@ static inline void add_offset_pair(
|
||||
}
|
||||
|
||||
if (name) {
|
||||
Z_ADDREF(match_pair);
|
||||
zend_hash_update(Z_ARRVAL_P(result), name, &match_pair);
|
||||
add_named(result, name, &match_pair, start_offset == PCRE2_UNSET);
|
||||
}
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair);
|
||||
}
|
||||
@ -1054,8 +1067,7 @@ static void populate_subpat_array(
|
||||
populate_match_value(
|
||||
&val, subject, offsets[2*i], offsets[2*i+1], unmatched_as_null);
|
||||
if (subpat_names[i]) {
|
||||
Z_TRY_ADDREF(val);
|
||||
zend_hash_update(Z_ARRVAL_P(subpats), subpat_names[i], &val);
|
||||
add_named(subpats, subpat_names[i], &val, offsets[2*i] == PCRE2_UNSET);
|
||||
}
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &val);
|
||||
}
|
||||
@ -1063,7 +1075,7 @@ static void populate_subpat_array(
|
||||
for (i = count; i < num_subpats; i++) {
|
||||
ZVAL_NULL(&val);
|
||||
if (subpat_names[i]) {
|
||||
zend_hash_update(Z_ARRVAL_P(subpats), subpat_names[i], &val);
|
||||
zend_hash_add(Z_ARRVAL_P(subpats), subpat_names[i], &val);
|
||||
}
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &val);
|
||||
}
|
||||
|
218
ext/pcre/tests/bug79257.phpt
Normal file
218
ext/pcre/tests/bug79257.phpt
Normal file
@ -0,0 +1,218 @@
|
||||
--TEST--
|
||||
Bug #79257: Duplicate named groups (?J) prefer last alternative even if not matched
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))/', 'foo', $matches);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))/', 'foo', $matches,
|
||||
PREG_UNMATCHED_AS_NULL);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))/', 'foo', $matches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))/', 'foo', $matches,
|
||||
PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE);
|
||||
var_dump($matches);
|
||||
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))(?<h>baz)/', 'foobaz', $matches);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))(?<h>baz)/', 'foobaz', $matches,
|
||||
PREG_UNMATCHED_AS_NULL);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))(?<h>baz)/', 'foobaz', $matches,
|
||||
PREG_OFFSET_CAPTURE);
|
||||
var_dump($matches);
|
||||
preg_match('/(?J)(?:(?<g>foo)|(?<g>bar))(?<h>baz)/', 'foobaz', $matches,
|
||||
PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE);
|
||||
var_dump($matches);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
["g"]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
string(3) "foo"
|
||||
}
|
||||
array(4) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
["g"]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
string(3) "foo"
|
||||
[2]=>
|
||||
NULL
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
["g"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
}
|
||||
array(4) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
["g"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
int(-1)
|
||||
}
|
||||
}
|
||||
array(6) {
|
||||
[0]=>
|
||||
string(6) "foobaz"
|
||||
["g"]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
string(3) "foo"
|
||||
[2]=>
|
||||
string(0) ""
|
||||
["h"]=>
|
||||
string(3) "baz"
|
||||
[3]=>
|
||||
string(3) "baz"
|
||||
}
|
||||
array(6) {
|
||||
[0]=>
|
||||
string(6) "foobaz"
|
||||
["g"]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
string(3) "foo"
|
||||
[2]=>
|
||||
NULL
|
||||
["h"]=>
|
||||
string(3) "baz"
|
||||
[3]=>
|
||||
string(3) "baz"
|
||||
}
|
||||
array(6) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(6) "foobaz"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
["g"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(0) ""
|
||||
[1]=>
|
||||
int(-1)
|
||||
}
|
||||
["h"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "baz"
|
||||
[1]=>
|
||||
int(3)
|
||||
}
|
||||
[3]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "baz"
|
||||
[1]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
||||
array(6) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(6) "foobaz"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
["g"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "foo"
|
||||
[1]=>
|
||||
int(0)
|
||||
}
|
||||
[2]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
int(-1)
|
||||
}
|
||||
["h"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "baz"
|
||||
[1]=>
|
||||
int(3)
|
||||
}
|
||||
[3]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(3) "baz"
|
||||
[1]=>
|
||||
int(3)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user