diff options
Diffstat (limited to 'src/regparse.c')
-rw-r--r-- | src/regparse.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/regparse.c b/src/regparse.c index 8f1d1cb..11f9e34 100644 --- a/src/regparse.c +++ b/src/regparse.c @@ -108,6 +108,38 @@ onig_warning(const char* s) (*onig_warn)(s); } +#define DEFAULT_MAX_CAPTURE_NUM 32767 + +static int MaxCaptureNum = DEFAULT_MAX_CAPTURE_NUM; + +extern int +onig_set_capture_num_limit(int num) +{ + if (num < 0) return -1; + + MaxCaptureNum = num; + return 0; +} + +static unsigned int ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT; + +extern unsigned int +onig_get_parse_depth_limit(void) +{ + return ParseDepthLimit; +} + +extern int +onig_set_parse_depth_limit(unsigned int depth) +{ + if (depth == 0) + ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT; + else + ParseDepthLimit = depth; + return 0; +} + + static void bbuf_free(BBuf* bbuf) { @@ -959,6 +991,7 @@ scan_env_clear(ScanEnv* env) env->curr_max_regnum = 0; env->has_recursion = 0; #endif + env->parse_depth = 0; } static int @@ -968,7 +1001,7 @@ scan_env_add_mem_entry(ScanEnv* env) Node** p; need = env->num_mem + 1; - if (need > ONIG_MAX_CAPTURE_NUM) + if (need > MaxCaptureNum && MaxCaptureNum != 0) return ONIGERR_TOO_MANY_CAPTURES; if (need >= SCANENV_MEMNODES_SIZE) { @@ -1639,9 +1672,10 @@ add_code_range_to_buf(BBuf** pbuf, OnigCodePoint from, OnigCodePoint to) bound = x; } - for (high = low, bound = n; high < bound; ) { + high = (to == ~((OnigCodePoint )0)) ? n : low; + for (bound = n; high < bound; ) { x = (high + bound) >> 1; - if (to >= data[x*2] - 1) + if (to + 1 >= data[x*2]) high = x + 1; else bound = x; @@ -4113,8 +4147,11 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end, enum CCVALTYPE val_type, in_type; int val_israw, in_israw; - prev_cc = (CClassNode* )NULL; *np = NULL_NODE; + env->parse_depth++; + if (env->parse_depth > ParseDepthLimit) + return ONIGERR_PARSE_DEPTH_LIMIT_OVER; + prev_cc = (CClassNode* )NULL; r = fetch_token_in_cc(tok, src, end, env); if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) { neg = 1; @@ -4315,7 +4352,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end, if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) { CC_ESC_WARN(env, (UChar* )"-"); - goto any_char_in; /* [0-9-a] is allowed as [0-9\-a] */ + goto range_end_val; /* [0-9-a] is allowed as [0-9\-a] */ } r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS; goto err; @@ -4420,6 +4457,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end, } } *src = p; + env->parse_depth--; return 0; err: @@ -5281,6 +5319,9 @@ parse_subexp(Node** top, OnigToken* tok, int term, Node *node, **headp; *top = NULL; + env->parse_depth++; + if (env->parse_depth > ParseDepthLimit) + return ONIGERR_PARSE_DEPTH_LIMIT_OVER; r = parse_branch(&node, tok, term, src, end, env); if (r < 0) { onig_node_free(node); @@ -5317,6 +5358,7 @@ parse_subexp(Node** top, OnigToken* tok, int term, return ONIGERR_PARSER_BUG; } + env->parse_depth--; return r; } |