From 5bd1bbdc50f9a56056cd8aec97f6ad04e5ffce4e Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Thu, 26 Feb 2026 17:14:53 +0100 Subject: [PATCH] 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 --- UPGRADING | 5 +++ ext/pcre/php_pcre.c | 5 +++ ext/pcre/tests/preg_grep_error_utf8.phpt | 44 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 ext/pcre/tests/preg_grep_error_utf8.phpt diff --git a/UPGRADING b/UPGRADING index 77d8463afe9..e034d0b0235 100644 --- a/UPGRADING +++ b/UPGRADING @@ -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. diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 4efe0542b76..72a923e650b 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -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; + } } /* }}} */ diff --git a/ext/pcre/tests/preg_grep_error_utf8.phpt b/ext/pcre/tests/preg_grep_error_utf8.phpt new file mode 100644 index 00000000000..efdd7632ab7 --- /dev/null +++ b/ext/pcre/tests/preg_grep_error_utf8.phpt @@ -0,0 +1,44 @@ +--TEST-- +preg_grep() returns false on match execution error (e.g. malformed UTF-8) +--FILE-- + +--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)