From a99595cc3a688b8850da6d770c4bcab78d027441 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 1 Sep 2016 19:15:32 +0900 Subject: [PATCH 1/5] Implement RF bug #72777 --- ext/mbstring/mbstring.c | 25 +++++++++++++++++++++ ext/mbstring/mbstring.h | 5 +++-- ext/mbstring/tests/mbregex_stack_limit.phpt | 24 ++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 ext/mbstring/tests/mbregex_stack_limit.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index b92a0abede8f4..5f22b5d7f5254 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1473,6 +1473,28 @@ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes) return SUCCESS; } /* }}} */ + +/* {{{ static PHP_INI_MH(OnUpdate_regex_stack_limit */ +static PHP_INI_MH(OnUpdate_regex_stack_limit) +{ + zend_long stack_limit; + + /* keep the compiler happy */ + (void)entry; (void)mh_arg2; (void)mh_arg3; (void)stage; + + 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; +} +/* }}} */ /* }}} */ /* {{{ php.ini directive registration */ @@ -1499,6 +1521,9 @@ PHP_INI_BEGIN() PHP_INI_ALL, OnUpdateLong, strict_detection, zend_mbstring_globals, mbstring_globals) +#if HAVE_MBREGEX + STD_PHP_INI_ENTRY("mbstring.regex_stack_limit", "10000", PHP_INI_ALL, OnUpdate_regex_stack_limit, regex_stack_limit, zend_mbstring_globals, mbstring_globals) +#endif PHP_INI_END() /* }}} */ diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 9021a3a454c70..2249456901f01 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -190,9 +190,10 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring) long strict_detection; long illegalchars; mbfl_buffer_converter *outconv; - void *http_output_conv_mimetypes; + void *http_output_conv_mimetypes; #if HAVE_MBREGEX - struct _zend_mb_regex_globals *mb_regex_globals; + struct _zend_mb_regex_globals *mb_regex_globals; + zend_long regex_stack_limit; /* Dummy */ #endif ZEND_END_MODULE_GLOBALS(mbstring) 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 From 38f398eed035c0abecb3ecab1a4906632d8b0762 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 1 Sep 2016 19:46:01 +0900 Subject: [PATCH 2/5] Remove global var usage --- ext/mbstring/mbstring.c | 5 +---- ext/mbstring/mbstring.h | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 5f22b5d7f5254..97d0912ed63ee 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1479,9 +1479,6 @@ static PHP_INI_MH(OnUpdate_regex_stack_limit) { zend_long stack_limit; - /* keep the compiler happy */ - (void)entry; (void)mh_arg2; (void)mh_arg3; (void)stage; - stack_limit = atol(ZSTR_VAL(new_value)); if (stack_limit > 0 && stack_limit <= UINT_MAX) { onig_set_match_stack_limit_size(stack_limit); @@ -1522,7 +1519,7 @@ PHP_INI_BEGIN() OnUpdateLong, strict_detection, zend_mbstring_globals, mbstring_globals) #if HAVE_MBREGEX - STD_PHP_INI_ENTRY("mbstring.regex_stack_limit", "10000", PHP_INI_ALL, OnUpdate_regex_stack_limit, regex_stack_limit, zend_mbstring_globals, mbstring_globals) + PHP_INI_ENTRY("mbstring.regex_stack_limit", "10000", PHP_INI_ALL, OnUpdate_regex_stack_limit) #endif PHP_INI_END() /* }}} */ diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 2249456901f01..9021a3a454c70 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -190,10 +190,9 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring) long strict_detection; long illegalchars; mbfl_buffer_converter *outconv; - void *http_output_conv_mimetypes; + void *http_output_conv_mimetypes; #if HAVE_MBREGEX - struct _zend_mb_regex_globals *mb_regex_globals; - zend_long regex_stack_limit; /* Dummy */ + struct _zend_mb_regex_globals *mb_regex_globals; #endif ZEND_END_MODULE_GLOBALS(mbstring) From c416d5ee073e90e22e2ccc64fd93b41ba066c46f Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 1 Sep 2016 20:09:50 +0900 Subject: [PATCH 3/5] Add test --- ext/mbstring/tests/mbregex_stack_limit2.phpt | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ext/mbstring/tests/mbregex_stack_limit2.phpt diff --git a/ext/mbstring/tests/mbregex_stack_limit2.phpt b/ext/mbstring/tests/mbregex_stack_limit2.phpt new file mode 100644 index 0000000000000..0dd7327feb110 --- /dev/null +++ b/ext/mbstring/tests/mbregex_stack_limit2.phpt @@ -0,0 +1,24 @@ +--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 From 00cfae6c3cf7879bed45942b06bdea309e506253 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 5 Sep 2016 15:56:12 +0900 Subject: [PATCH 4/5] Fix limit condition. Increase stack limit from 10k to 100k. --- ext/mbstring/mbstring.c | 4 ++-- ext/mbstring/tests/mbregex_stack_limit2.phpt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 97d0912ed63ee..37b152031dfec 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1482,7 +1482,7 @@ static PHP_INI_MH(OnUpdate_regex_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) { + } 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"); @@ -1519,7 +1519,7 @@ PHP_INI_BEGIN() OnUpdateLong, strict_detection, zend_mbstring_globals, mbstring_globals) #if HAVE_MBREGEX - PHP_INI_ENTRY("mbstring.regex_stack_limit", "10000", PHP_INI_ALL, OnUpdate_regex_stack_limit) + 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_limit2.phpt b/ext/mbstring/tests/mbregex_stack_limit2.phpt index 0dd7327feb110..12c8c8edab216 100644 --- a/ext/mbstring/tests/mbregex_stack_limit2.phpt +++ b/ext/mbstring/tests/mbregex_stack_limit2.phpt @@ -14,6 +14,7 @@ function mb_trim( $string, $chars = "", $chars_array = array() ) return $string; } +ini_set('mbstring.regex_stack_limit', 10000); var_dump(mb_trim(str_repeat(' ', 10000))); echo 'OK'; From ba4fecea7940b1ec4fbc4867fbb431b413aeeeb5 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 22 Sep 2016 11:08:40 +0900 Subject: [PATCH 5/5] Add #if HAVE_MBREGEX --- ext/mbstring/mbstring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7d59ef0da8346..ff325f155682b 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1474,6 +1474,7 @@ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes) } /* }}} */ +#if HAVE_MBREGEX /* {{{ static PHP_INI_MH(OnUpdate_regex_stack_limit */ static PHP_INI_MH(OnUpdate_regex_stack_limit) { @@ -1491,6 +1492,7 @@ static PHP_INI_MH(OnUpdate_regex_stack_limit) return SUCCESS; } +#endif /* }}} */ /* }}} */