diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 2a7bba0368489..ff325f155682b 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1473,6 +1473,27 @@ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes) return SUCCESS; } /* }}} */ + +#if HAVE_MBREGEX +/* {{{ static PHP_INI_MH(OnUpdate_regex_stack_limit */ +static PHP_INI_MH(OnUpdate_regex_stack_limit) +{ + zend_long stack_limit; + + stack_limit = atol(ZSTR_VAL(new_value)); + if (stack_limit > 0 && stack_limit <= UINT_MAX) { + onig_set_match_stack_limit_size(stack_limit); + } else if (stack_limit <= 0) { + onig_set_match_stack_limit_size(UINT_MAX); + } else { + php_error_docref("ref.mbstring", E_WARNING, "mbstring.regex_stack_limit exceeds UNIT_MAX"); + return FAILURE; + } + + return SUCCESS; +} +#endif +/* }}} */ /* }}} */ /* {{{ php.ini directive registration */ @@ -1499,6 +1520,9 @@ PHP_INI_BEGIN() PHP_INI_ALL, OnUpdateLong, strict_detection, zend_mbstring_globals, mbstring_globals) +#if HAVE_MBREGEX + PHP_INI_ENTRY("mbstring.regex_stack_limit", "100000", PHP_INI_ALL, OnUpdate_regex_stack_limit) +#endif PHP_INI_END() /* }}} */ diff --git a/ext/mbstring/tests/mbregex_stack_limit.phpt b/ext/mbstring/tests/mbregex_stack_limit.phpt new file mode 100644 index 0000000000000..9d0f3acc9d414 --- /dev/null +++ b/ext/mbstring/tests/mbregex_stack_limit.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test oniguruma stack limit +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +int(1) +OK diff --git a/ext/mbstring/tests/mbregex_stack_limit2.phpt b/ext/mbstring/tests/mbregex_stack_limit2.phpt new file mode 100644 index 0000000000000..12c8c8edab216 --- /dev/null +++ b/ext/mbstring/tests/mbregex_stack_limit2.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test oniguruma stack limit +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: mb_ereg_replace(): mbregex search failure in php_mbereg_replace_exec(): match-stack limit over in %s on line %d +string(0) "" +OK