Skip to content

Commit 9f7a4bc

Browse files
zhou1615Girgias
authored andcommitted
Fix a NULL pointer dereference bug lead by php_pcre_replace_impl()
php_pcre_replace_impl() will return NULL on failure. However, in the implementation of RegexIterator::accept() the return value of php_pcre_replace_impl() is directly used without any check, which leads to a NULL pointer dereference. Fix this by adding a NULL check, and returning false in that case. Closes GH-8271 Signed-off-by: George Peter Banyard <[email protected]>
1 parent 49b2ff5 commit 9f7a4bc

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

ext/spl/spl_iterators.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,11 @@ PHP_METHOD(RegexIterator, accept)
18661866
}
18671867

18681868
result = php_pcre_replace_impl(intern->u.regex.pce, subject, ZSTR_VAL(subject), ZSTR_LEN(subject), replacement_str, -1, &count);
1869+
zend_string_release(replacement_str);
1870+
1871+
if (!result) {
1872+
RETURN_FALSE;
1873+
}
18691874

18701875
if (intern->u.regex.flags & REGIT_USE_KEY) {
18711876
zval_ptr_dtor(&intern->current.key);
@@ -1875,7 +1880,6 @@ PHP_METHOD(RegexIterator, accept)
18751880
ZVAL_STR(&intern->current.data, result);
18761881
}
18771882

1878-
zend_string_release(replacement_str);
18791883
RETVAL_BOOL(count > 0);
18801884
}
18811885
}

ext/spl/tests/gh8271.phpt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
GH-8271: NULL pointer dereference in RegexIterator::accept()
3+
--EXTENSIONS--
4+
spl
5+
--FILE--
6+
<?php
7+
function words() {
8+
yield "f\xC3oo";
9+
yield "bar";
10+
yield "baz";
11+
}
12+
13+
$it = new RegexIterator(words(), '/a/u', RegexIterator::REPLACE);
14+
var_dump(iterator_to_array($it));
15+
16+
function wordsForEach() {
17+
foreach (["f\xC3oo", "bar", "baz"] as $word) {
18+
yield $word;
19+
}
20+
}
21+
$it = new RegexIterator(wordsForEach(), '/a/u', RegexIterator::REPLACE);
22+
var_dump(iterator_to_array($it));
23+
24+
?>
25+
--EXPECT--
26+
array(2) {
27+
[1]=>
28+
string(2) "br"
29+
[2]=>
30+
string(2) "bz"
31+
}
32+
array(2) {
33+
[1]=>
34+
string(2) "br"
35+
[2]=>
36+
string(2) "bz"
37+
}

0 commit comments

Comments
 (0)