diff --git a/oniguruma/README.md b/oniguruma/README.md index b02a86b05..01900e1e8 100644 --- a/oniguruma/README.md +++ b/oniguruma/README.md @@ -30,6 +30,8 @@ Supported character encodings: Master branch ------------- +* NEW API: retry limit in search functions +* Limit on maximum nesting level of subexp call (16) * Fixed behavior of isolated options in Perl and Java syntaxes. /...(?i).../ diff --git a/oniguruma/doc/API b/oniguruma/doc/API index 43d53385a..c1fb2c991 100644 --- a/oniguruma/doc/API +++ b/oniguruma/doc/API @@ -1,4 +1,4 @@ -Oniguruma API Version 6.9.4 2019/09/30 +Oniguruma API Version 6.9.5 2020/02/13 #include @@ -273,6 +273,20 @@ Oniguruma API Version 6.9.4 2019/09/30 normal return: ONIG_NORMAL +# int onig_set_retry_limit_in_search_of_match_param(OnigMatchParam* mp, unsigned long limit) + + Set a retry limit count of a search process. + 0 means unlimited. + + If the value of this limit is not 0 and is smaller than the current value of the retry limit in match of mp, the value of retry limit in match is set to this limit. + + arguments + 1 mp: match-param pointer + 2 limit: number of limit + + normal return: ONIG_NORMAL + + # int onig_set_progress_callout_of_match_param(OnigMatchParam* mp, OnigCalloutFunc f) Set a function for callouts of contents in progress. @@ -333,7 +347,7 @@ Oniguruma API Version 6.9.4 2019/09/30 arguments 1-7: same as onig_search() - 8 mp: match parameter values (match_stack_limit, retry_limit_in_match) + 8 mp: match parameter values (match_stack_limit, retry_limit_in_match, retry_limit_in_search) # int onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, @@ -368,7 +382,7 @@ Oniguruma API Version 6.9.4 2019/09/30 arguments 1-6: same as onig_match() - 7 mp: match parameter values (match_stack_limit, retry_limit_in_match) + 7 mp: match parameter values (match_stack_limit, retry_limit_in_match, retry_limit_in_search) # int onig_scan(regex_t* reg, const UChar* str, const UChar* end, @@ -866,19 +880,38 @@ Oniguruma API Version 6.9.4 2019/09/30 # unsigned long onig_get_retry_limit_in_match(void) - Return the limit of retry counts in matching process. + Return the limit of retry counts in a matching process. (default: 10000000) - normal return: limit value + normal return: current limit value -# int onig_set_retry_limit_in_match(unsigned long n) +# unsigned long onig_get_retry_limit_in_search(void) + + Return the limit of retry counts in a search process. + 0 means unlimited. + (default: 0) + + normal return: current limit value + + +# int onig_set_retry_limit_in_match(unsigned long limit) Set the limit of retry counts in matching process. normal return: ONIG_NORMAL +# int onig_set_retry_limit_in_search(unsigned long limit) + + Set a retry limit count of a search process. + 0 means unlimited. + + If the value of this limit is not 0 and is smaller than the current value of the retry limit in match, the value of retry limit in match is set to this limit. + + normal return: ONIG_NORMAL + + # OnigCalloutFunc onig_get_progress_callout(void) Get a function for callouts of contents in progress. diff --git a/oniguruma/src/oniguruma.h b/oniguruma/src/oniguruma.h index 1cf0963f7..aea8866bb 100644 --- a/oniguruma/src/oniguruma.h +++ b/oniguruma/src/oniguruma.h @@ -576,6 +576,7 @@ ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax; #define ONIGERR_MATCH_STACK_LIMIT_OVER -15 #define ONIGERR_PARSE_DEPTH_LIMIT_OVER -16 #define ONIGERR_RETRY_LIMIT_IN_MATCH_OVER -17 +#define ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER -18 #define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21 #define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22 #define ONIGERR_FAIL_TO_INITIALIZE -23 @@ -924,6 +925,10 @@ unsigned long onig_get_retry_limit_in_match P_((void)); ONIG_EXTERN int onig_set_retry_limit_in_match P_((unsigned long n)); ONIG_EXTERN +unsigned long onig_get_retry_limit_in_search P_((void)); +ONIG_EXTERN +int onig_set_retry_limit_in_search P_((unsigned long n)); +ONIG_EXTERN unsigned int onig_get_parse_depth_limit P_((void)); ONIG_EXTERN int onig_set_capture_num_limit P_((int num)); @@ -952,6 +957,8 @@ int onig_set_match_stack_limit_size_of_match_param P_((OnigMatchParam* param, un ONIG_EXTERN int onig_set_retry_limit_in_match_of_match_param P_((OnigMatchParam* param, unsigned long limit)); ONIG_EXTERN +int onig_set_retry_limit_in_search_of_match_param P_((OnigMatchParam* param, unsigned long limit)); +ONIG_EXTERN int onig_set_progress_callout_of_match_param P_((OnigMatchParam* param, OnigCalloutFunc f)); ONIG_EXTERN int onig_set_retraction_callout_of_match_param P_((OnigMatchParam* param, OnigCalloutFunc f)); diff --git a/oniguruma/src/regcomp.c b/oniguruma/src/regcomp.c index 5f6cdda2d..4dbbd567a 100644 --- a/oniguruma/src/regcomp.c +++ b/oniguruma/src/regcomp.c @@ -408,12 +408,12 @@ onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag) } static int -int_multiply_cmp(int x, int y, int v) +len_multiply_cmp(OnigLen x, int y, OnigLen v) { if (x == 0 || y == 0) return -1; - if (x < INT_MAX / y) { - int xy = x * y; + if (x < INFINITE_LEN / y) { + OnigLen xy = x * (OnigLen )y; if (xy > v) return 1; else { if (xy == v) return 0; @@ -421,7 +421,7 @@ int_multiply_cmp(int x, int y, int v) } } else - return 1; + return v == INFINITE_LEN ? 0 : 1; } extern int @@ -429,7 +429,7 @@ onig_positive_int_multiply(int x, int y) { if (x == 0 || y == 0) return 0; - if (x < INT_MAX / y) + if (x < ONIG_INT_MAX / y) return x * y; else return -1; @@ -1394,7 +1394,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) /* anychar repeat */ if (is_anychar_infinite_greedy(qn)) { if (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0) { + len_multiply_cmp((OnigLen )tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0) { if (IS_NOT_NULL(qn->next_head_exact)) return OPSIZE_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower; else @@ -1408,7 +1408,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) if (infinite && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) { len = OPSIZE_JUMP; } @@ -1439,7 +1439,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) } else if (!infinite && qn->greedy && (qn->upper == 1 || - int_multiply_cmp(tlen + OPSIZE_PUSH, qn->upper, + len_multiply_cmp((OnigLen )tlen + OPSIZE_PUSH, qn->upper, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { len = tlen * qn->lower; len += (OPSIZE_PUSH + tlen) * (qn->upper - qn->lower); @@ -1467,7 +1467,8 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) if (is_anychar_infinite_greedy(qn) && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp((OnigLen )tlen, qn->lower, + QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { r = compile_tree_n_times(NODE_QUANT_BODY(qn), qn->lower, reg, env); if (r != 0) return r; if (IS_NOT_NULL(qn->next_head_exact)) { @@ -1491,7 +1492,8 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) if (infinite && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp((OnigLen )tlen, qn->lower, + QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { int addr; if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) { @@ -1586,7 +1588,7 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) } else if (! infinite && qn->greedy && (qn->upper == 1 || - int_multiply_cmp(tlen + OPSIZE_PUSH, qn->upper, + len_multiply_cmp((OnigLen )tlen + OPSIZE_PUSH, qn->upper, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { int n = qn->upper - qn->lower; @@ -4826,11 +4828,13 @@ is_all_code_len_1_items(int n, OnigCaseFoldCodeItem items[]) } static int -get_min_max_byte_len_case_fold_items(int n, OnigCaseFoldCodeItem items[], int* rmin, int* rmax) +get_min_max_byte_len_case_fold_items(int n, OnigCaseFoldCodeItem items[], + OnigLen* rmin, OnigLen* rmax) { - int i, len, minlen, maxlen; + int i; + OnigLen len, minlen, maxlen; - minlen = INT_MAX; + minlen = INFINITE_LEN; maxlen = 0; for (i = 0; i < n; i++) { OnigCaseFoldCodeItem* item = items + i; @@ -4925,7 +4929,7 @@ unravel_cf_string_add(Node** rlist, Node** rsn, UChar* s, UChar* end, static int unravel_cf_string_alt_or_cc_add(Node** rlist, int n, - OnigCaseFoldCodeItem items[], int byte_len, OnigEncoding enc, + OnigCaseFoldCodeItem items[], OnigEncoding enc, OnigCaseFoldType case_fold_flag, UChar* s, UChar* end) { int r, i; @@ -4982,7 +4986,7 @@ unravel_cf_string_alt_or_cc_add(Node** rlist, int n, static int unravel_cf_look_behind_add(Node** rlist, Node** rsn, int n, OnigCaseFoldCodeItem items[], OnigEncoding enc, - UChar* s, int one_len) + UChar* s, OnigLen one_len) { int r, i, found; @@ -5028,7 +5032,8 @@ unravel_cf_look_behind_add(Node** rlist, Node** rsn, static int unravel_case_fold_string(Node* node, regex_t* reg, int state) { - int r, n, one_len, min_len, max_len, in_look_behind; + int r, n, in_look_behind; + OnigLen min_len, max_len, one_len; UChar *start, *end, *p, *q; StrNode* snode; Node *sn, *list; @@ -5056,7 +5061,7 @@ unravel_case_fold_string(Node* node, regex_t* reg, int state) goto err; } - one_len = enclen(enc, p); + one_len = (OnigLen )enclen(enc, p); if (n == 0) { q = p + one_len; r = unravel_cf_string_add(&list, &sn, p, q, 0 /* flag */); @@ -5082,7 +5087,7 @@ unravel_case_fold_string(Node* node, regex_t* reg, int state) } q = p + max_len; - r = unravel_cf_string_alt_or_cc_add(&list, n, items, max_len, enc, + r = unravel_cf_string_alt_or_cc_add(&list, n, items, enc, reg->case_fold_flag, p, q); if (r != 0) goto err; sn = NULL_NODE; @@ -7347,6 +7352,9 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, #endif #ifdef USE_CALLOUT || (IS_NOT_NULL(reg->extp) && reg->extp->callout_num != 0) +#endif +#ifdef USE_CALL + || scan_env.num_call > 0 #endif ) reg->stack_pop_level = STACK_POP_LEVEL_ALL; diff --git a/oniguruma/src/regerror.c b/oniguruma/src/regerror.c index ab0decd67..e4e252cf1 100644 --- a/oniguruma/src/regerror.c +++ b/oniguruma/src/regerror.c @@ -55,6 +55,8 @@ onig_error_code_to_format(int code) p = "parse depth limit over"; break; case ONIGERR_RETRY_LIMIT_IN_MATCH_OVER: p = "retry-limit-in-match over"; break; + case ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER: + p = "retry-limit-in-search over"; break; case ONIGERR_TYPE_BUG: p = "undefined type (bug)"; break; case ONIGERR_PARSER_BUG: diff --git a/oniguruma/src/regexec.c b/oniguruma/src/regexec.c index 76fd754fb..ad477c4b9 100644 --- a/oniguruma/src/regexec.c +++ b/oniguruma/src/regexec.c @@ -35,6 +35,10 @@ #include "regint.h" +#pragma warning( push ) +#pragma warning( disable : 4018 ) + + #define IS_MBC_WORD_ASCII_MODE(enc,s,end,mode) \ ((mode) == 0 ? ONIGENC_IS_MBC_WORD(enc,s,end) : ONIGENC_IS_MBC_WORD_ASCII(enc,s,end)) @@ -72,7 +76,10 @@ typedef struct { struct OnigMatchParamStruct { unsigned int match_stack_limit; +#ifdef USE_RETRY_LIMIT unsigned long retry_limit_in_match; + unsigned long retry_limit_in_search; +#endif #ifdef USE_CALLOUT OnigCalloutFunc progress_callout_of_contents; OnigCalloutFunc retraction_callout_of_contents; @@ -95,8 +102,27 @@ extern int onig_set_retry_limit_in_match_of_match_param(OnigMatchParam* param, unsigned long limit) { +#ifdef USE_RETRY_LIMIT param->retry_limit_in_match = limit; return ONIG_NORMAL; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif +} + +extern int +onig_set_retry_limit_in_search_of_match_param(OnigMatchParam* param, + unsigned long limit) +{ +#ifdef USE_RETRY_LIMIT + param->retry_limit_in_search = limit; + if (limit != 0 && param->retry_limit_in_match > limit) + param->retry_limit_in_match = limit; + + return ONIG_NORMAL; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif } extern int @@ -141,7 +167,11 @@ typedef struct { int ptr_num; const UChar* start; /* search start position (for \G: BEGIN_POSITION) */ unsigned int match_stack_limit; +#ifdef USE_RETRY_LIMIT unsigned long retry_limit_in_match; + unsigned long retry_limit_in_search; + unsigned long retry_limit_in_search_counter; +#endif OnigMatchParam* mp; #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE int best_len; /* for ONIG_OPTION_FIND_LONGEST */ @@ -1026,8 +1056,8 @@ onig_region_copy(OnigRegion* to, OnigRegion* from) #endif #define STK_EMPTY_CHECK_END 0x5000 /* for recursive call */ #define STK_MEM_END_MARK 0x8100 -#define STK_CALL_FRAME 0x0400 -#define STK_RETURN 0x0500 +#define STK_CALL_FRAME (0x0400 | STK_MASK_POP_HANDLED) +#define STK_RETURN (0x0500 | STK_MASK_POP_HANDLED) #define STK_SAVE_VAL 0x0600 #define STK_MARK 0x0704 @@ -1147,6 +1177,21 @@ struct OnigCalloutArgsStruct { #endif /* USE_REPEAT_AND_EMPTY_CHECK_LOCAL_VAR */ +#ifdef USE_RETRY_LIMIT +#define RETRY_IN_MATCH_ARG_INIT(msa,mpv) \ + (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + (msa).retry_limit_in_search = (mpv)->retry_limit_in_search;\ + (msa).retry_limit_in_search_counter = 0; +#else +#define RETRY_IN_MATCH_ARG_INIT(msa,mpv) +#endif + +#ifdef USE_CALL +#define POP_CALL else if (stk->type == STK_RETURN) {subexp_call_nest_counter++;} else if (stk->type == STK_CALL_FRAME) {subexp_call_nest_counter--;} +#else +#define POP_CALL +#endif + #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE #define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mpv) do { \ (msa).stack_p = (void* )0;\ @@ -1154,7 +1199,7 @@ struct OnigCalloutArgsStruct { (msa).region = (arg_region);\ (msa).start = (arg_start);\ (msa).match_stack_limit = (mpv)->match_stack_limit;\ - (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + RETRY_IN_MATCH_ARG_INIT(msa,mpv)\ (msa).mp = mpv;\ (msa).best_len = ONIG_MISMATCH;\ (msa).ptr_num = PTR_NUM_SIZE(reg);\ @@ -1166,7 +1211,7 @@ struct OnigCalloutArgsStruct { (msa).region = (arg_region);\ (msa).start = (arg_start);\ (msa).match_stack_limit = (mpv)->match_stack_limit;\ - (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + RETRY_IN_MATCH_ARG_INIT(msa,mpv)\ (msa).mp = mpv;\ (msa).ptr_num = PTR_NUM_SIZE(reg);\ } while(0) @@ -1210,7 +1255,7 @@ struct OnigCalloutArgsStruct { #define STACK_SAVE do{\ - msa->stack_n = (int )(stk_end - stk_base);\ + msa->stack_n = (int )(stk_end - stk_base);\ if (is_alloca != 0) {\ size_t size = sizeof(StackIndex) * msa->ptr_num \ + sizeof(StackType) * msa->stack_n;\ @@ -1238,9 +1283,10 @@ onig_set_match_stack_limit_size(unsigned int size) return 0; } -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT -static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; +static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; +static unsigned long RetryLimitInSearch = DEFAULT_RETRY_LIMIT_IN_SEARCH; #define CHECK_RETRY_LIMIT_IN_MATCH do {\ if (retry_in_match_counter++ > retry_limit_in_match) {\ @@ -1252,24 +1298,47 @@ static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; #define CHECK_RETRY_LIMIT_IN_MATCH -#endif /* USE_RETRY_LIMIT_IN_MATCH */ +#endif /* USE_RETRY_LIMIT */ extern unsigned long onig_get_retry_limit_in_match(void) { -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT return RetryLimitInMatch; #else - /* return ONIG_NO_SUPPORT_CONFIG; */ return 0; #endif } extern int -onig_set_retry_limit_in_match(unsigned long size) +onig_set_retry_limit_in_match(unsigned long n) { -#ifdef USE_RETRY_LIMIT_IN_MATCH - RetryLimitInMatch = size; +#ifdef USE_RETRY_LIMIT + RetryLimitInMatch = n; + return 0; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif +} + +extern unsigned long +onig_get_retry_limit_in_search(void) +{ +#ifdef USE_RETRY_LIMIT + return RetryLimitInSearch; +#else + return 0; +#endif +} + +extern int +onig_set_retry_limit_in_search(unsigned long n) +{ +#ifdef USE_RETRY_LIMIT + RetryLimitInSearch = n; + if (n != 0 && RetryLimitInMatch > n) + RetryLimitInMatch = n; + return 0; #else return ONIG_NO_SUPPORT_CONFIG; @@ -1318,8 +1387,9 @@ extern int onig_initialize_match_param(OnigMatchParam* mp) { mp->match_stack_limit = MatchStackLimit; -#ifdef USE_RETRY_LIMIT_IN_MATCH - mp->retry_limit_in_match = RetryLimitInMatch; +#ifdef USE_RETRY_LIMIT + mp->retry_limit_in_match = RetryLimitInMatch; + mp->retry_limit_in_search = RetryLimitInSearch; #endif #ifdef USE_CALLOUT @@ -1521,9 +1591,9 @@ onig_set_callout_data_by_callout_args_self(OnigCalloutArgs* args, static int -stack_double(int is_alloca, char** arg_alloc_base, - StackType** arg_stk_base, StackType** arg_stk_end, StackType** arg_stk, - MatchArg* msa) +stack_double(int* is_alloca, char** arg_alloc_base, + StackType** arg_stk_base, StackType** arg_stk_end, + StackType** arg_stk, MatchArg* msa) { unsigned int n; int used; @@ -1542,18 +1612,21 @@ stack_double(int is_alloca, char** arg_alloc_base, size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n; n *= 2; new_size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n; - if (is_alloca != 0) { + if (*is_alloca != 0) { new_alloc_base = (char* )xmalloc(new_size); if (IS_NULL(new_alloc_base)) { STACK_SAVE; return ONIGERR_MEMORY; } xmemcpy(new_alloc_base, alloc_base, size); + *is_alloca = 0; } else { if (msa->match_stack_limit != 0 && n > msa->match_stack_limit) { - if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit) + if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit) { + STACK_SAVE; return ONIGERR_MATCH_STACK_LIMIT_OVER; + } else n = msa->match_stack_limit; } @@ -1576,9 +1649,8 @@ stack_double(int is_alloca, char** arg_alloc_base, #define STACK_ENSURE(n) do {\ if ((int )(stk_end - stk) < (n)) {\ - int r = stack_double(is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\ - if (r != 0) { STACK_SAVE; return r; } \ - is_alloca = 0;\ + int r = stack_double(&is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\ + if (r != 0) return r;\ UPDATE_FOR_STACK_REALLOC;\ }\ } while(0) @@ -1921,6 +1993,7 @@ stack_double(int is_alloca, char** arg_alloc_base, }\ POP_REPEAT_INC \ POP_EMPTY_CHECK_START \ + POP_CALL \ POP_CALLOUT_CASE\ }\ }\ @@ -1947,6 +2020,7 @@ stack_double(int is_alloca, char** arg_alloc_base, }\ POP_REPEAT_INC \ POP_EMPTY_CHECK_START \ + POP_CALL \ /* Don't call callout here because negation of total success by (?!..) (?options; OnigEncoding encode = reg->enc; OnigCaseFoldType case_fold_flag = reg->case_fold_flag; +#ifdef USE_CALL + unsigned long subexp_call_nest_counter = 0; +#endif #ifdef ONIG_DEBUG_MATCH static unsigned int counter = 1; @@ -2749,7 +2827,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, msa->mp->match_at_call_counter++; #endif -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT retry_limit_in_match = msa->retry_limit_in_match; #endif @@ -2773,7 +2851,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, STACK_PUSH_BOTTOM(STK_ALT, FinishCode); /* bottom stack */ INIT_RIGHT_RANGE; -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT retry_in_match_counter = 0; #endif @@ -3794,8 +3872,6 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, CASE_OP(POP) STACK_POP_ONE; - /* for stop backtrack */ - /* CHECK_RETRY_LIMIT_IN_MATCH; */ INC_OP; JUMP_OUT; @@ -3900,14 +3976,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, #ifdef USE_CALL CASE_OP(CALL) + if (subexp_call_nest_counter == SUBEXP_CALL_MAX_NEST_LEVEL) + goto fail; + subexp_call_nest_counter++; addr = p->call.addr; INC_OP; STACK_PUSH_CALL_FRAME(p); p = reg->ops + addr; + JUMP_OUT; CASE_OP(RETURN) STACK_RETURN(p); STACK_PUSH_RETURN; + subexp_call_nest_counter--; JUMP_OUT; #endif @@ -4138,6 +4219,15 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, } BYTECODE_INTERPRETER_END; match_at_end: + if (msa->retry_limit_in_search != 0) { + if (retry_in_match_counter > ULONG_MAX - msa->retry_limit_in_search_counter) + best_len = ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER; + else { + msa->retry_limit_in_search_counter += retry_in_match_counter; + if (msa->retry_limit_in_search_counter > msa->retry_limit_in_search) + best_len = ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER; + } + } STACK_SAVE; return best_len; } @@ -6389,6 +6479,8 @@ onig_setup_builtin_monitors_by_ascii_encoded_name(void* fp /* FILE* */) return ONIG_NORMAL; } +#pragma warning( pop ) + #endif /* ONIG_NO_PRINT */ #endif /* USE_CALLOUT */ diff --git a/oniguruma/src/regint.h b/oniguruma/src/regint.h index 837045c77..1efd60c7e 100644 --- a/oniguruma/src/regint.h +++ b/oniguruma/src/regint.h @@ -64,7 +64,7 @@ #define USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT /* /(?:()|())*\2/ */ #define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */ #define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR -#define USE_RETRY_LIMIT_IN_MATCH +#define USE_RETRY_LIMIT #ifdef USE_GOTO_LABELS_AS_VALUES #define USE_THREADED_CODE #define USE_DIRECT_THREADED_CODE @@ -86,7 +86,9 @@ #define INIT_MATCH_STACK_SIZE 160 #define DEFAULT_MATCH_STACK_LIMIT_SIZE 0 /* unlimited */ #define DEFAULT_RETRY_LIMIT_IN_MATCH 10000000 +#define DEFAULT_RETRY_LIMIT_IN_SEARCH 0 /* unlimited */ #define DEFAULT_PARSE_DEPTH_LIMIT 4096 +#define SUBEXP_CALL_MAX_NEST_LEVEL 16 #include "regenc.h" @@ -180,9 +182,14 @@ #define CHECK_NULL_RETURN_MEMERR(p) if (IS_NULL(p)) return ONIGERR_MEMORY #define NULL_UCHARP ((UChar* )0) +#ifndef ONIG_INT_MAX +#define ONIG_INT_MAX INT_MAX +#endif + #define CHAR_MAP_SIZE 256 #define INFINITE_LEN ONIG_INFINITE_DISTANCE -#define LOOK_BEHIND_MAX_CHAR_LEN INT_MAX +#define STEP_BACK_MAX_CHAR_LEN 65535 /* INT_MAX is too big */ +#define LOOK_BEHIND_MAX_CHAR_LEN STEP_BACK_MAX_CHAR_LEN /* escape other system UChar definition */ #ifdef ONIG_ESCAPE_UCHAR_COLLISION diff --git a/oniguruma/src/regparse.c b/oniguruma/src/regparse.c index 784ea567b..54f92e2c8 100644 --- a/oniguruma/src/regparse.c +++ b/oniguruma/src/regparse.c @@ -3456,7 +3456,7 @@ scan_number(UChar** src, const UChar* end, OnigEncoding enc) PFETCH(c); if (IS_CODE_DIGIT_ASCII(enc, c)) { val = (int )DIGITVAL(c); - if ((INT_MAX - val) / 10 < num) + if ((ONIG_INT_MAX - val) / 10 < num) return -1; /* overflow */ num = num * 10 + val;