diff options
Diffstat (limited to 'regcomp.c')
-rw-r--r-- | regcomp.c | 124 |
1 files changed, 102 insertions, 22 deletions
@@ -195,8 +195,7 @@ unset_addr_list_init(UnsetAddrList* uslist, int size) static void unset_addr_list_end(UnsetAddrList* uslist) { - if (IS_NOT_NULL(uslist->us)) - xfree(uslist->us); + xfree(uslist->us); } static int @@ -1274,6 +1273,10 @@ compile_length_enclose_node(EncloseNode* node, regex_t* reg) break; case ENCLOSE_STOP_BACKTRACK: + /* Disable POP_STOP_BT optimization for simple repeat under the match cache */ + /* optimization because the match cache optimization pushes an extra item to */ + /* the stack and it breaks the assumption for this optimization. */ +#ifndef USE_MATCH_CACHE if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) { QtfrNode* qn = NQTFR(node->target); tlen = compile_length_tree(qn->target, reg); @@ -1283,8 +1286,11 @@ compile_length_enclose_node(EncloseNode* node, regex_t* reg) + SIZE_OP_PUSH + tlen + SIZE_OP_POP + SIZE_OP_JUMP; } else { +#endif len = SIZE_OP_PUSH_STOP_BT + tlen + SIZE_OP_POP_STOP_BT; +#ifndef USE_MATCH_CACHE } +#endif break; case ENCLOSE_CONDITION: @@ -1396,6 +1402,10 @@ compile_enclose_node(EncloseNode* node, regex_t* reg) break; case ENCLOSE_STOP_BACKTRACK: + /* Disable POP_STOP_BT optimization for simple repeat under the match cache */ + /* optimization because the match cache optimization pushes an extra item to */ + /* the stack and it breaks the assumption for this optimization. */ +#ifndef USE_MATCH_CACHE if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) { QtfrNode* qn = NQTFR(node->target); r = compile_tree_n_times(qn->target, qn->lower, reg); @@ -1414,12 +1424,15 @@ compile_enclose_node(EncloseNode* node, regex_t* reg) -((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP + (int )SIZE_OP_JUMP)); } else { +#endif r = add_opcode(reg, OP_PUSH_STOP_BT); if (r) return r; r = compile_tree(node->target, reg); if (r) return r; r = add_opcode(reg, OP_POP_STOP_BT); +#ifndef USE_MATCH_CACHE } +#endif break; case ENCLOSE_CONDITION: @@ -3382,7 +3395,7 @@ next_setup(Node* node, Node* next_node, regex_t* reg) } else if (type == NT_ENCLOSE) { EncloseNode* en = NENCLOSE(node); - if (en->type == ENCLOSE_MEMORY) { + if (en->type == ENCLOSE_MEMORY && !IS_ENCLOSE_CALLED(en)) { node = en->target; goto retry; } @@ -5483,10 +5496,8 @@ clear_optimize_info(regex_t* reg) reg->sub_anchor = 0; reg->exact_end = (UChar* )NULL; reg->threshold_len = 0; - if (IS_NOT_NULL(reg->exact)) { - xfree(reg->exact); - reg->exact = (UChar* )NULL; - } + xfree(reg->exact); + reg->exact = (UChar* )NULL; } #ifdef ONIG_DEBUG @@ -5649,12 +5660,12 @@ extern void onig_free_body(regex_t* reg) { if (IS_NOT_NULL(reg)) { - if (IS_NOT_NULL(reg->p)) xfree(reg->p); - if (IS_NOT_NULL(reg->exact)) xfree(reg->exact); - if (IS_NOT_NULL(reg->int_map)) xfree(reg->int_map); - if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward); - if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range); - if (IS_NOT_NULL(reg->chain)) onig_free(reg->chain); + xfree(reg->p); + xfree(reg->exact); + xfree(reg->int_map); + xfree(reg->int_map_backward); + xfree(reg->repeat_range); + onig_free(reg->chain); #ifdef USE_NAMED_GROUP onig_names_free(reg); @@ -5671,6 +5682,80 @@ onig_free(regex_t* reg) } } +static void* +dup_copy(const void *ptr, size_t size) +{ + void *newptr = xmalloc(size); + if (IS_NOT_NULL(newptr)) { + memcpy(newptr, ptr, size); + } + return newptr; +} + +extern int +onig_reg_copy(regex_t** nreg, regex_t* oreg) +{ + if (IS_NOT_NULL(oreg)) { + regex_t *reg = *nreg = (regex_t* )xmalloc(sizeof(regex_t)); + if (IS_NULL(reg)) return ONIGERR_MEMORY; + + *reg = *oreg; + +# define COPY_FAILED(mem, size) IS_NULL(reg->mem = dup_copy(reg->mem, size)) + + if (IS_NOT_NULL(reg->exact)) { + size_t exact_size = reg->exact_end - reg->exact; + if (COPY_FAILED(exact, exact_size)) + goto err; + (reg)->exact_end = (reg)->exact + exact_size; + } + + if (IS_NOT_NULL(reg->int_map)) { + if (COPY_FAILED(int_map, sizeof(int) * ONIG_CHAR_TABLE_SIZE)) + goto err_int_map; + } + if (IS_NOT_NULL(reg->int_map_backward)) { + if (COPY_FAILED(int_map_backward, sizeof(int) * ONIG_CHAR_TABLE_SIZE)) + goto err_int_map_backward; + } + if (IS_NOT_NULL(reg->p)) { + if (COPY_FAILED(p, reg->alloc)) + goto err_p; + } + if (IS_NOT_NULL(reg->repeat_range)) { + if (COPY_FAILED(repeat_range, reg->repeat_range_alloc * sizeof(OnigRepeatRange))) + goto err_repeat_range; + } + if (IS_NOT_NULL(reg->name_table)) { + if (onig_names_copy(reg, oreg)) + goto err_name_table; + } + if (IS_NOT_NULL(reg->chain)) { + if (onig_reg_copy(®->chain, reg->chain)) + goto err_chain; + } + return 0; +# undef COPY_FAILED + + err_chain: + onig_names_free(reg); + err_name_table: + xfree(reg->repeat_range); + err_repeat_range: + xfree(reg->p); + err_p: + xfree(reg->int_map_backward); + err_int_map_backward: + xfree(reg->int_map); + err_int_map: + xfree(reg->exact); + err: + xfree(reg); + return ONIGERR_MEMORY; + } + return 0; +} + #ifdef RUBY size_t onig_memsize(const regex_t *reg) @@ -5927,8 +6012,8 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, } onig_node_free(root); - if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) - xfree(scan_env.mem_nodes_dynamic); + xfree(scan_env.mem_nodes_dynamic); + return r; } @@ -6000,20 +6085,15 @@ onig_new(regex_t** reg, const UChar* pattern, const UChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo) { - int r; - *reg = (regex_t* )xmalloc(sizeof(regex_t)); if (IS_NULL(*reg)) return ONIGERR_MEMORY; - r = onig_reg_init(*reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax); - if (r) goto err; - - r = onig_compile(*reg, pattern, pattern_end, einfo); + int r = onig_new_without_alloc(*reg, pattern, pattern_end, option, enc, syntax, einfo); if (r) { - err: onig_free(*reg); *reg = NULL; } + return r; } |