summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-19 15:03:26 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-19 15:03:26 +0000
commitc3fd3191fc9801b43daa0125d1df1ced383011b8 (patch)
tree501ae1d112a98c224e69c269aa04ba1ea6f715ad /regexec.c
parent661148ad9efac4c2701e0e540323fd487e75d5bf (diff)
merge r46831 partially. extracted commits are as follows.
https://github.com/k-takata/Onigmo/commit/b9fba1dc63ccb42a86e934011b468e6022fabb74 https://github.com/k-takata/Onigmo/commit/c1fc76b9bd463948ffc5058bc352bf93732f0314 https://github.com/k-takata/Onigmo/commit/a0efc0a200f7108ca3d5ac3039c8f952e0051619 https://github.com/k-takata/Onigmo/commit/c7cda4ed5676167b0d01bb5555724f6164fbdb13 [Bug #8716] * include/ruby/oniguruma.h (ONIG_MAX_CAPTURE_GROUP_NUM, ONIGERR_TOO_MANY_CAPTURE_GROUPS): add cheking the number of capture groups. * regerror.c (onig_error_code_to_format): ditto. * regparse.c (scan_env_add_mem_entry): ditto. * regexec.c (onig_region_copy, match_at): fix: segmation fault occurs when many groups are used. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47223 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'regexec.c')
-rw-r--r--regexec.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/regexec.c b/regexec.c
index 997849695e..973d3eac00 100644
--- a/regexec.c
+++ b/regexec.c
@@ -444,9 +444,26 @@ onig_region_copy(OnigRegion* to, OnigRegion* from)
-#define STACK_INIT(alloc_addr, ptr_num, stack_num) do {\
- if (msa->stack_p) {\
+#define MAX_PTR_NUM 100
+
+#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num) do {\
+ if (ptr_num > MAX_PTR_NUM) {\
+ alloc_addr = (char* )xmalloc(sizeof(OnigStackIndex) * (ptr_num));\
+ heap_addr = alloc_addr;\
+ if (msa->stack_p) {\
+ stk_alloc = (OnigStackType* )(msa->stack_p);\
+ stk_base = stk_alloc;\
+ stk = stk_base;\
+ stk_end = stk_base + msa->stack_n;\
+ } else {\
+ stk_alloc = (OnigStackType* )xalloca(sizeof(OnigStackType) * (stack_num));\
+ stk_base = stk_alloc;\
+ stk = stk_base;\
+ stk_end = stk_base + (stack_num);\
+ }\
+ } else if (msa->stack_p) {\
alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num));\
+ heap_addr = NULL;\
stk_alloc = (OnigStackType* )(msa->stack_p);\
stk_base = stk_alloc;\
stk = stk_base;\
@@ -455,6 +472,7 @@ onig_region_copy(OnigRegion* to, OnigRegion* from)
else {\
alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num)\
+ sizeof(OnigStackType) * (stack_num));\
+ heap_addr = NULL;\
stk_alloc = (OnigStackType* )(alloc_addr + sizeof(OnigStackIndex) * (ptr_num));\
stk_base = stk_alloc;\
stk = stk_base;\
@@ -529,7 +547,11 @@ stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
#define STACK_ENSURE(n) do {\
if (stk_end - stk < (n)) {\
int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
- if (r != 0) { STACK_SAVE; return r; } \
+ if (r != 0) {\
+ STACK_SAVE;\
+ if (xmalloc_base) xfree(xmalloc_base);\
+ return r;\
+ }\
}\
} while(0)
@@ -1325,6 +1347,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
UChar *p = reg->p;
UChar *pkeep;
char *alloca_base;
+ char *xmalloc_base = NULL;
OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
OnigStackType *stkp; /* used as any purpose. */
OnigStackIndex si;
@@ -1340,7 +1363,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
/* Stack #0 is used to store the pattern itself and used for (?R), \g<0>, etc. */
n = reg->num_repeat + (reg->num_mem + 1) * 2;
- STACK_INIT(alloca_base, n, INIT_MATCH_STACK_SIZE);
+ STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
pop_level = reg->stack_pop_level;
num_mem = reg->num_mem;
repeat_stk = (OnigStackIndex* )alloca_base;
@@ -1354,7 +1377,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
/* Stack #0 not is used. */
n = reg->num_repeat + reg->num_mem * 2;
- STACK_INIT(alloca_base, n, INIT_MATCH_STACK_SIZE);
+ STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
pop_level = reg->stack_pop_level;
num_mem = reg->num_mem;
repeat_stk = (OnigStackIndex* )alloca_base;
@@ -2916,20 +2939,24 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
finish:
STACK_SAVE;
+ if (xmalloc_base) xfree(xmalloc_base);
return best_len;
#ifdef ONIG_DEBUG
stack_error:
STACK_SAVE;
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_STACK_BUG;
#endif
bytecode_error:
STACK_SAVE;
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_UNDEFINED_BYTECODE;
unexpected_bytecode_error:
STACK_SAVE;
+ if (xmalloc_base) xfree(xmalloc_base);
return ONIGERR_UNEXPECTED_BYTECODE;
}