summaryrefslogtreecommitdiff
path: root/ext/mbstring/php_mbregex.c
diff options
context:
space:
mode:
authorYasuo Ohgaki <yohgaki@php.net>2016-09-01 19:15:32 +0900
committerStanislav Malyshev <stas@php.net>2019-03-28 00:31:57 -0700
commit738016bd884a339009e1af371eaba0fee60bf23b (patch)
tree1b46e398ce25f03bde6f737a7f4cd5e16b918700 /ext/mbstring/php_mbregex.c
parent218154e6958bc911ee2640baca10854cb2c33e20 (diff)
downloadphp-git-738016bd884a339009e1af371eaba0fee60bf23b.tar.gz
Implement RF bug #72777 - ensure stack limits on mbstring functions.
The patch creates new config: mbstring.regex_stack_limit, which defaults to 100000.
Diffstat (limited to 'ext/mbstring/php_mbregex.c')
-rw-r--r--ext/mbstring/php_mbregex.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c
index 319ee567c6..10c7f3e272 100644
--- a/ext/mbstring/php_mbregex.c
+++ b/ext/mbstring/php_mbregex.c
@@ -850,6 +850,23 @@ PHP_FUNCTION(mb_regex_encoding)
}
/* }}} */
+/* {{{ _php_mb_onig_search */
+static int _php_mb_onig_search(regex_t* reg, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start,
+ const OnigUChar* range, OnigRegion* region, OnigOptionType option) {
+ OnigMatchParam *mp = onig_new_match_param();
+ int err;
+ onig_initialize_match_param(mp);
+ 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));
+ }
+ /* search */
+ err = onig_search_with_param(reg, str, end, start, range, region, option, mp);
+ onig_free_match_param(mp);
+ return err;
+}
+/* }}} */
+
+
/* {{{ _php_mb_regex_ereg_exec */
static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
{
@@ -909,7 +926,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
regs = onig_region_new();
/* actually execute the regular expression */
- if (onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, (OnigUChar *)(string + string_len), regs, 0) < 0) {
+ if (_php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, (OnigUChar *)(string + string_len), regs, 0) < 0) {
RETVAL_FALSE;
goto out;
}
@@ -1086,7 +1103,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
string_lim = (OnigUChar*)(string + string_len);
regs = onig_region_new();
while (err >= 0) {
- err = onig_search(re, (OnigUChar *)string, (OnigUChar *)string_lim, pos, (OnigUChar *)string_lim, regs, 0);
+ err = _php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)string_lim, pos, (OnigUChar *)string_lim, regs, 0);
if (err <= -2) {
OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
onig_error_code_to_str(err_str, err);
@@ -1262,7 +1279,7 @@ PHP_FUNCTION(mb_split)
/* churn through str, generating array entries as we go */
while (count != 0 && (size_t)(pos - (OnigUChar *)string) < string_len) {
size_t beg, end;
- err = onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), pos, (OnigUChar *)(string + string_len), regs, 0);
+ err = _php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), pos, (OnigUChar *)(string + string_len), regs, 0);
if (err < 0) {
break;
}
@@ -1319,6 +1336,7 @@ PHP_FUNCTION(mb_ereg_match)
OnigSyntaxType *syntax;
OnigOptionType option = 0;
int err;
+ OnigMatchParam *mp;
{
char *option_str = NULL;
@@ -1342,8 +1360,14 @@ PHP_FUNCTION(mb_ereg_match)
RETURN_FALSE;
}
+ mp = onig_new_match_param();
+ onig_initialize_match_param(mp);
+ 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));
+ }
/* match */
- err = onig_match(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0);
+ err = onig_match_with_param(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0, mp);
+ onig_free_match_param(mp);
if (err >= 0) {
RETVAL_TRUE;
} else {
@@ -1406,7 +1430,7 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode)
}
MBREX(search_regs) = onig_region_new();
- err = onig_search(MBREX(search_re), str, str + len, str + pos, str + len, MBREX(search_regs), 0);
+ err = _php_mb_onig_search(MBREX(search_re), str, str + len, str + pos, str + len, MBREX(search_regs), 0);
if (err == ONIG_MISMATCH) {
MBREX(search_pos) = len;
RETVAL_FALSE;