Skip to content

Commit 1b091dc

Browse files
authored
Forbid \C in UTF-8 patterns (#21139)
Fixes GH-21134
1 parent 3163ac7 commit 1b091dc

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ PHP NEWS
1616
. Fixed bug GH-22779 (mb_strrpos() returns the wrong position for a negative
1717
offset in a non-UTF-8 encoding). (Eyüp Can Akman)
1818

19+
- PCRE:
20+
. Fixed bug GH-21134 (Crash with \C + UTF-8). Using \C in UTF-8 patterns is
21+
now forbidden. (Arnaud)
22+
1923
- Sockets:
2024
. Fixed various memory related issues in ext/sockets. (David Carlier)
2125

ext/pcre/php_pcre.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
734734
#ifdef PCRE2_UCP
735735
coptions |= PCRE2_UCP;
736736
#endif
737+
/* The \C escape sequence is unsafe in PCRE2_UTF mode */
738+
coptions |= PCRE2_NEVER_BACKSLASH_C;
737739
break;
738740
case 'J': coptions |= PCRE2_DUPNAMES; break;
739741

@@ -787,8 +789,13 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
787789
if (key != regex) {
788790
zend_string_release_ex(key, 0);
789791
}
790-
pcre2_get_error_message(errnumber, error, sizeof(error));
791-
php_error_docref(NULL,E_WARNING, "Compilation failed: %s at offset %zu", error, erroffset);
792+
const char *err_msg = (const char*) error;
793+
if (errnumber == PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED) {
794+
err_msg = "using \\C is incompatible with the 'u' modifier";
795+
} else {
796+
pcre2_get_error_message(errnumber, error, sizeof(error));
797+
}
798+
php_error_docref(NULL,E_WARNING, "Compilation failed: %s at offset %zu", err_msg, erroffset);
792799
pcre_handle_exec_error(PCRE2_ERROR_INTERNAL);
793800
efree(pattern);
794801
return NULL;

ext/pcre/tests/gh21134.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-21134: ASan negative-size-param in preg_match_all() with \C + UTF-8 multibyte input
3+
--CREDITS--
4+
vi3tL0u1s
5+
--FILE--
6+
<?php
7+
8+
$r = preg_match_all("/(.*)\\C/u", "à", $m);
9+
var_dump($r, $m);
10+
11+
?>
12+
--EXPECTF--
13+
Warning: preg_match_all(): Compilation failed: using \C is incompatible with the 'u' modifier at offset 6 in %s on line %d
14+
bool(false)
15+
NULL

0 commit comments

Comments
 (0)