summaryrefslogtreecommitdiff
path: root/src/regparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regparse.c')
-rw-r--r--src/regparse.c52
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;
}