From 963d8d782fc98fb6dc3a66f0068795f9920c269d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 27 Jan 2005 19:08:10 +0000 Subject: [BZ #558] Update. 2005-01-27 Paolo Bonzini [BZ #558] * posix/regcomp.c (calc_inveclosure): Return reg_errcode_t. Initialize the node sets in dfa->inveclosures. (analyze): Initialize inveclosures only if it is needed. Check errors from calc_inveclosure. * posix/regex_internal.c (re_dfa_add_node): Do not initialize the inveclosure node set. * posix/regexec.c (re_search_internal): If nmatch includes unused subexpressions, reset them to { rm_so: -1, rm_eo: -1 } here. * posix/regcomp.c (parse_bracket_exp) [!RE_ENABLE_I18N]: Do build a SIMPLE_BRACKET token. * posix/regexec.c (transit_state_mb): Do not examine nodes where ACCEPT_MB is not set. --- posix/regcomp.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'posix/regcomp.c') diff --git a/posix/regcomp.c b/posix/regcomp.c index cf759690cf..1a5f7952c3 100644 --- a/posix/regcomp.c +++ b/posix/regcomp.c @@ -58,7 +58,7 @@ static int search_duplicated_node (re_dfa_t *dfa, int org_node, static reg_errcode_t calc_eclosure (re_dfa_t *dfa); static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root); -static void calc_inveclosure (re_dfa_t *dfa); +static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); static int fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax); static void fetch_token (re_token_t *result, re_string_t *input, @@ -1132,9 +1132,8 @@ analyze (preg) dfa->org_indices = re_malloc (int, dfa->nodes_alloc); dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); - dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_alloc); if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL - || dfa->eclosures == NULL || dfa->inveclosures == NULL, 0)) + || dfa->eclosures == NULL, 0)) return REG_ESPACE; dfa->subexp_map = re_malloc (int, preg->re_nsub); @@ -1167,7 +1166,18 @@ analyze (preg) ret = calc_eclosure (dfa); if (BE (ret != REG_NOERROR, 0)) return ret; - calc_inveclosure (dfa); + + /* We only need this during the prune_impossible_nodes pass in regexec.c; + skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ + if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) + || dfa->nbackref) + { + dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); + if (BE (dfa->inveclosures == NULL, 0)) + return REG_ESPACE; + ret = calc_inveclosure (dfa); + } + return ret; } @@ -1597,19 +1607,26 @@ duplicate_node (new_idx, dfa, org_idx, constraint) return REG_NOERROR; } -static void +static reg_errcode_t calc_inveclosure (dfa) re_dfa_t *dfa; { - int src, idx, dest; + int src, idx, ret; + for (idx = 0; idx < dfa->nodes_len; ++idx) + re_node_set_init_empty (dfa->inveclosures + idx); + for (src = 0; src < dfa->nodes_len; ++src) { + int *elems = dfa->eclosures[src].elems; for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) { - dest = dfa->eclosures[src].elems[idx]; - re_node_set_insert_last (dfa->inveclosures + dest, src); + ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); + if (BE (ret == -1, 0)) + return REG_ESPACE; } } + + return REG_NOERROR; } /* Calculate "eclosure" for all the node in DFA. */ @@ -3304,17 +3321,18 @@ parse_bracket_exp (regexp, dfa, token, syntax, err) } } else +#endif /* not RE_ENABLE_I18N */ { +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* Build a tree for simple bracket. */ br_token.type = SIMPLE_BRACKET; br_token.opr.sbcset = sbcset; work_tree = create_token_tree (dfa, NULL, NULL, &br_token); if (BE (work_tree == NULL, 0)) goto parse_bracket_exp_espace; - - free_charset (mbcset); } -#endif /* not RE_ENABLE_I18N */ return work_tree; parse_bracket_exp_espace: -- cgit v1.2.1