Mercurial > vim
changeset 6533:bdc8e71633e4 v7.4.593
updated for version 7.4.593
Problem: Crash when searching for "x\{0,90000}". (Dominique Pelle)
Solution: Bail out from the NFA engine when the max limit is much higher
than the min limit.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Tue, 27 Jan 2015 12:59:55 +0100 |
parents | 357f273b9cbd |
children | 47b3f1674787 |
files | src/regexp.c src/regexp_nfa.c src/version.c src/vim.h |
diffstat | 4 files changed, 21 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/regexp.c +++ b/src/regexp.c @@ -8081,7 +8081,8 @@ vim_regcomp(expr_arg, re_flags) * First try the NFA engine, unless backtracking was requested. */ if (regexp_engine != BACKTRACKING_ENGINE) - prog = nfa_regengine.regcomp(expr, re_flags); + prog = nfa_regengine.regcomp(expr, + re_flags + (regexp_engine == AUTOMATIC_ENGINE ? RE_AUTO : 0)); else prog = bt_regengine.regcomp(expr, re_flags); @@ -8105,16 +8106,14 @@ vim_regcomp(expr_arg, re_flags) #endif /* * If the NFA engine failed, try the backtracking engine. - * Disabled for now, both engines fail on the same patterns. - * Re-enable when regcomp() fails when the pattern would work better - * with the other engine. - * + * The NFA engine also fails for patterns that it can't handle well + * but are still valid patterns, thus a retry should work. + */ if (regexp_engine == AUTOMATIC_ENGINE) { + regexp_engine = BACKTRACKING_ENGINE; prog = bt_regengine.regcomp(expr, re_flags); - regexp_engine == BACKTRACKING_ENGINE; } - */ } if (prog != NULL)
--- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -244,6 +244,9 @@ static char_u e_nul_found[] = N_("E865: static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); static char_u e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %ld"); +/* re_flags passed to nfa_regcomp() */ +static int nfa_re_flags; + /* NFA regexp \ze operator encountered. */ static int nfa_has_zend; @@ -2011,10 +2014,10 @@ nfa_regpiece() * <atom>* */ if (minval == 0 && maxval == MAX_LIMIT) { - if (greedy) + if (greedy) /* { { (match the braces) */ /* \{}, \{0,} */ EMIT(NFA_STAR); - else + else /* { { (match the braces) */ /* \{-}, \{-0,} */ EMIT(NFA_STAR_NONGREEDY); break; @@ -2030,6 +2033,12 @@ nfa_regpiece() return OK; } + /* The engine is very inefficient (uses too many states) when the + * maximum is much larger than the minimum. Bail out if we can + * use the other engine. */ + if ((nfa_re_flags & RE_AUTO) && maxval > minval + 200) + return FAIL; + /* Ignore previous call to nfa_regatom() */ post_ptr = post_start + my_post_start; /* Save parse state after the repeated atom and the \{} */ @@ -7046,6 +7055,7 @@ nfa_regcomp(expr, re_flags) return NULL; nfa_regengine.expr = expr; + nfa_re_flags = re_flags; init_class_tab();
--- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 593, +/**/ 592, /**/ 591,
--- a/src/vim.h +++ b/src/vim.h @@ -1020,6 +1020,7 @@ extern char *(*dyn_libintl_textdomain)(c #define RE_MAGIC 1 /* 'magic' option */ #define RE_STRING 2 /* match in string instead of buffer text */ #define RE_STRICT 4 /* don't allow [abc] without ] */ +#define RE_AUTO 8 /* automatic engine selection */ #ifdef FEAT_SYN_HL /* values for reg_do_extmatch */