Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ext/pcre/php_pcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -2986,6 +2986,11 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
if (match_data != mdata) {
pcre2_match_data_free(match_data);
}

if (PCRE_G(error_code) != PHP_PCRE_NO_ERROR) {
zend_array_destroy(Z_ARR_P(return_value));
RETVAL_FALSE;
}
}
/* }}} */

Expand Down
44 changes: 44 additions & 0 deletions ext/pcre/tests/preg_grep_error_utf8.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
--TEST--
preg_grep() returns false on match execution error (e.g. malformed UTF-8)
--FILE--
<?php
// preg_grep should return false when a match execution error occurs,
// consistent with preg_match behavior. See GH-11936.

// Test 1: preg_match returns false on malformed UTF-8 with /u modifier
var_dump(preg_match('/.*/u', hex2bin('ff')));
var_dump(preg_last_error() === PREG_BAD_UTF8_ERROR);

// Test 2: preg_grep should also return false (not an empty/partial array)
var_dump(preg_grep('/.*/u', [hex2bin('ff')]));
var_dump(preg_last_error() === PREG_BAD_UTF8_ERROR);

// Test 3: preg_grep with valid entries before the invalid one should
// return false, not a partial array
var_dump(preg_grep('/.*/u', ['foo', hex2bin('ff'), 'bar']));
var_dump(preg_last_error() === PREG_BAD_UTF8_ERROR);

// Test 4: preg_grep with PREG_GREP_INVERT should also return false on error
var_dump(preg_grep('/.*/u', [hex2bin('ff')], PREG_GREP_INVERT));
var_dump(preg_last_error() === PREG_BAD_UTF8_ERROR);

// Test 5: preg_grep without error still returns an array
var_dump(preg_grep('/.*/u', ['foo', 'bar']));
var_dump(preg_last_error() === PREG_NO_ERROR);
?>
--EXPECTF--
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
array(2) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
}
bool(true)
Loading