mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
ext/pcre: Fix preg_grep() returning partial array instead of false on error (#21260)
When a PCRE execution error occurs (e.g. malformed UTF-8 with /u modifier), preg_grep() was returning a partial result array containing only the entries processed before the error. All other preg_* functions return false on execution errors. After the match loop, check PCRE_G(error_code) and if an error occurred, destroy the partial array and return false instead. Fixes GH-11936
This commit is contained in:
@@ -19,6 +19,11 @@ PHP 8.6 UPGRADE NOTES
|
||||
1. Backward Incompatible Changes
|
||||
========================================
|
||||
|
||||
- PCRE:
|
||||
. preg_grep() now returns false instead of a partial array when a PCRE
|
||||
execution error occurs (e.g. malformed UTF-8 input with the /u modifier).
|
||||
This is consistent with other preg_* functions.
|
||||
|
||||
- Phar:
|
||||
. Invalid values now throw in Phar::mungServer() instead of being silently
|
||||
ignored.
|
||||
|
||||
@@ -2987,6 +2987,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));
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
44
ext/pcre/tests/preg_grep_error_utf8.phpt
Normal file
44
ext/pcre/tests/preg_grep_error_utf8.phpt
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user