mirror of
https://github.com/php/php-src.git
synced 2024-11-23 09:54:15 +08:00
Add support for mbstring.regex_retry_limit
This is very similar to the existing mbstring.regex_stack_limit, but for backtracking. The default value matches pcre.backtrack_limit. Only used on libonig >= 2.8.0.
This commit is contained in:
parent
b078ae6c01
commit
6623e7ac51
@ -268,6 +268,10 @@ PHP 7.4 UPGRADE NOTES
|
||||
. Added mb_str_split() function, which provides the same functionality as
|
||||
str_split(), but operating on code points rather than bytes.
|
||||
RFC: https://wiki.php.net/rfc/mb_str_split
|
||||
. Added mbstring.regex_retry_limit ini setting defaulting to 1000000. It
|
||||
limits the amount of backtracking that may be performed during one mbregex
|
||||
match and thus protects against exponential backtracking attacks (ReDOS).
|
||||
This setting only takes effect when linking against oniguruma >= 2.8.0.
|
||||
|
||||
- OPcache:
|
||||
. Support for preloading code has been added.
|
||||
|
@ -65,6 +65,7 @@ typedef void OnigMatchParam;
|
||||
#define onig_new_match_param() (NULL)
|
||||
#define onig_initialize_match_param(x) (void)(x)
|
||||
#define onig_set_match_stack_limit_size_of_match_param(x, y)
|
||||
#define onig_set_retry_limit_in_match_of_match_param(x, y)
|
||||
#define onig_free_match_param(x)
|
||||
#define onig_search_with_param(reg, str, end, start, range, region, option, mp) \
|
||||
onig_search(reg, str, end, start, range, region, option)
|
||||
@ -1029,6 +1030,9 @@ static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_stack_limit))) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_retry_limit))) {
|
||||
onig_set_retry_limit_in_match_of_match_param(mp, (unsigned int)MBSTRG(regex_retry_limit));
|
||||
}
|
||||
/* search */
|
||||
err = onig_search_with_param((php_mb_regex_t *)opaque, (const OnigUChar *)str,
|
||||
(const OnigUChar*)str + str_len, (const OnigUChar *)str,
|
||||
@ -1495,6 +1499,7 @@ PHP_INI_BEGIN()
|
||||
strict_detection, zend_mbstring_globals, mbstring_globals)
|
||||
#if HAVE_MBREGEX
|
||||
STD_PHP_INI_ENTRY("mbstring.regex_stack_limit", "100000",PHP_INI_ALL, OnUpdateLong, regex_stack_limit, zend_mbstring_globals, mbstring_globals)
|
||||
STD_PHP_INI_ENTRY("mbstring.regex_retry_limit", "1000000",PHP_INI_ALL, OnUpdateLong, regex_retry_limit, zend_mbstring_globals, mbstring_globals)
|
||||
#endif
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
|
@ -170,6 +170,9 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring)
|
||||
zend_bool internal_encoding_set;
|
||||
zend_bool http_output_set;
|
||||
zend_bool http_input_set;
|
||||
#if HAVE_MBREGEX
|
||||
zend_long regex_retry_limit;
|
||||
#endif
|
||||
ZEND_END_MODULE_GLOBALS(mbstring)
|
||||
|
||||
#define MB_OVERLOAD_MAIL 1
|
||||
|
@ -39,6 +39,7 @@ typedef void OnigMatchParam;
|
||||
#define onig_new_match_param() (NULL)
|
||||
#define onig_initialize_match_param(x) (void)(x)
|
||||
#define onig_set_match_stack_limit_size_of_match_param(x, y)
|
||||
#define onig_set_retry_limit_in_match_of_match_param(x, y)
|
||||
#define onig_free_match_param(x)
|
||||
#define onig_search_with_param(reg, str, end, start, range, region, option, mp) \
|
||||
onig_search(reg, str, end, start, range, region, option)
|
||||
@ -874,6 +875,9 @@ static int _php_mb_onig_search(regex_t* reg, const OnigUChar* str, const OnigUCh
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_stack_limit))) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_retry_limit))) {
|
||||
onig_set_retry_limit_in_match_of_match_param(mp, (unsigned int)MBSTRG(regex_retry_limit));
|
||||
}
|
||||
/* search */
|
||||
err = onig_search_with_param(reg, str, end, start, range, region, option, mp);
|
||||
onig_free_match_param(mp);
|
||||
@ -1395,9 +1399,12 @@ PHP_FUNCTION(mb_ereg_match)
|
||||
|
||||
mp = onig_new_match_param();
|
||||
onig_initialize_match_param(mp);
|
||||
if(MBSTRG(regex_stack_limit) > 0 && MBSTRG(regex_stack_limit) < UINT_MAX) {
|
||||
if (MBSTRG(regex_stack_limit) > 0 && MBSTRG(regex_stack_limit) < UINT_MAX) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
if (MBSTRG(regex_retry_limit) > 0 && MBSTRG(regex_retry_limit) < UINT_MAX) {
|
||||
onig_set_retry_limit_in_match_of_match_param(mp, (unsigned int)MBSTRG(regex_retry_limit));
|
||||
}
|
||||
/* match */
|
||||
err = onig_match_with_param(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0, mp);
|
||||
onig_free_match_param(mp);
|
||||
|
23
ext/mbstring/tests/retry_limit.phpt
Normal file
23
ext/mbstring/tests/retry_limit.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Oniguruma retry limit
|
||||
--SKIPIF--
|
||||
<?php
|
||||
extension_loaded('mbstring') or die('skip mbstring not available');
|
||||
if (!function_exists('mb_ereg')) die('skip mb_ereg not available');
|
||||
if (version_compare(MB_ONIGURUMA_VERSION, '6.8.0') < 0) {
|
||||
die('skip requires Oniguruma 6.8.0');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$regex = 'A(B|C+)+D|AC+X';
|
||||
$str = 'ACCCCCCCCCCCCCCCCCCCX';
|
||||
var_dump(mb_ereg($regex, $str));
|
||||
ini_set('mbstring.regex_retry_limit', '100000');
|
||||
var_dump(mb_ereg($regex, $str));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
bool(false)
|
@ -1692,6 +1692,11 @@ zend.assertions = 1
|
||||
; Default: 100000
|
||||
;mbstring.regex_stack_limit=100000
|
||||
|
||||
; This directive specifies maximum retry count for mbstring regular expressions. It is similar
|
||||
; to the pcre.backtrack_limit for PCRE.
|
||||
; Default: 1000000
|
||||
;mbstring.regex_retry_limit=1000000
|
||||
|
||||
[gd]
|
||||
; Tell the jpeg decode to ignore warnings and try to create
|
||||
; a gd image. The warning will then be displayed as notices
|
||||
|
@ -1694,6 +1694,11 @@ zend.assertions = -1
|
||||
; Default: 100000
|
||||
;mbstring.regex_stack_limit=100000
|
||||
|
||||
; This directive specifies maximum retry count for mbstring regular expressions. It is similar
|
||||
; to the pcre.backtrack_limit for PCRE.
|
||||
; Default: 1000000
|
||||
;mbstring.regex_retry_limit=1000000
|
||||
|
||||
[gd]
|
||||
; Tell the jpeg decode to ignore warnings and try to create
|
||||
; a gd image. The warning will then be displayed as notices
|
||||
|
Loading…
Reference in New Issue
Block a user