diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 5671957daac52..5150ce97202a7 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -734,6 +734,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo #ifdef PCRE2_UCP coptions |= PCRE2_UCP; #endif + /* The \C escape sequence is unsafe in PCRE2_UTF mode */ + coptions |= PCRE2_NEVER_BACKSLASH_C; break; case 'J': coptions |= PCRE2_DUPNAMES; break; @@ -787,7 +789,11 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo if (key != regex) { zend_string_release_ex(key, 0); } - pcre2_get_error_message(errnumber, error, sizeof(error)); + if (errnumber == PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED) { + strlcpy((char*)error, "using \\C is incompatible with the 'u' modifier", sizeof(error)); + } else { + pcre2_get_error_message(errnumber, error, sizeof(error)); + } php_error_docref(NULL,E_WARNING, "Compilation failed: %s at offset %zu", error, erroffset); pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); efree(pattern); diff --git a/ext/pcre/tests/gh21134.phpt b/ext/pcre/tests/gh21134.phpt new file mode 100644 index 0000000000000..ddcf19a6e7a27 --- /dev/null +++ b/ext/pcre/tests/gh21134.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-21134: ASan negative-size-param in preg_match_all() with \C + UTF-8 multibyte input +--CREDITS-- +vi3tL0u1s +--FILE-- + +--EXPECTF-- +Warning: preg_match_all(): Compilation failed: using \C is incompatible with the 'u' modifier at offset 6 in %s on line %d +bool(false) +NULL