summaryrefslogtreecommitdiff
path: root/src/regexp_nfa.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-11-05 14:27:36 +0100
committerBram Moolenaar <Bram@vim.org>2014-11-05 14:27:36 +0100
commitfda3729a064d6466cec6ac83dd1bfcc437ea4cc9 (patch)
tree7642145192f29ec2050ac8e9cc890ddc353615af /src/regexp_nfa.c
parent4f7e821f26019c14f4470deb0867c919548d5cd5 (diff)
downloadvim-git-fda3729a064d6466cec6ac83dd1bfcc437ea4cc9.tar.gz
updated for version 7.4.497v7.4.497
Problem: With some regexp patterns the NFA engine uses many states and becomes very slow. To the user it looks like Vim freezes. Solution: When the number of states reaches a limit fall back to the old engine. (Christian Brabandt)
Diffstat (limited to 'src/regexp_nfa.c')
-rw-r--r--src/regexp_nfa.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index 37635662b..91316094b 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -5522,6 +5522,13 @@ nfa_regmatch(prog, start, submatch, m)
nextlist->n = 0; /* clear nextlist */
nextlist->has_pim = FALSE;
++nfa_listid;
+ if (prog->re_engine == AUTOMATIC_ENGINE && nfa_listid >= NFA_MAX_STATES)
+ {
+ /* too many states, retry with old engine */
+ nfa_match = NFA_TOO_EXPENSIVE;
+ goto theend;
+ }
+
thislist->id = nfa_listid;
nextlist->id = nfa_listid + 1;
@@ -5704,6 +5711,11 @@ nfa_regmatch(prog, start, submatch, m)
*/
result = recursive_regmatch(t->state, NULL, prog,
submatch, m, &listids);
+ if (result == NFA_TOO_EXPENSIVE)
+ {
+ nfa_match = result;
+ goto theend;
+ }
/* for \@! and \@<! it is a match when the result is
* FALSE */
@@ -5817,6 +5829,11 @@ nfa_regmatch(prog, start, submatch, m)
/* First try matching the pattern. */
result = recursive_regmatch(t->state, NULL, prog,
submatch, m, &listids);
+ if (result == NFA_TOO_EXPENSIVE)
+ {
+ nfa_match = result;
+ goto theend;
+ }
if (result)
{
int bytelen;
@@ -6760,6 +6777,7 @@ nfa_regtry(prog, col)
int i;
regsubs_T subs, m;
nfa_state_T *start = prog->start;
+ int result;
#ifdef ENABLE_LOG
FILE *f;
#endif
@@ -6791,8 +6809,11 @@ nfa_regtry(prog, col)
clear_sub(&m.synt);
#endif
- if (nfa_regmatch(prog, start, &subs, &m) == FALSE)
+ result = nfa_regmatch(prog, start, &subs, &m);
+ if (result == FALSE)
return 0;
+ else if (result == NFA_TOO_EXPENSIVE)
+ return result;
cleanup_subexpr();
if (REG_MULTI)
@@ -6929,9 +6950,7 @@ nfa_regexec_both(line, startcol)
nfa_nsubexpr = prog->nsubexp;
nfa_listid = 1;
nfa_alt_listid = 2;
-#ifdef DEBUG
nfa_regengine.expr = prog->pattern;
-#endif
if (prog->reganch && col > 0)
return 0L;
@@ -6979,9 +6998,7 @@ nfa_regexec_both(line, startcol)
retval = nfa_regtry(prog, col);
-#ifdef DEBUG
nfa_regengine.expr = NULL;
-#endif
theend:
return retval;
@@ -7003,9 +7020,7 @@ nfa_regcomp(expr, re_flags)
if (expr == NULL)
return NULL;
-#ifdef DEBUG
nfa_regengine.expr = expr;
-#endif
init_class_tab();
@@ -7082,10 +7097,8 @@ nfa_regcomp(expr, re_flags)
/* Remember whether this pattern has any \z specials in it. */
prog->reghasz = re_has_z;
#endif
-#ifdef DEBUG
prog->pattern = vim_strsave(expr);
nfa_regengine.expr = NULL;
-#endif
out:
vim_free(post_start);
@@ -7099,9 +7112,7 @@ fail:
#ifdef ENABLE_LOG
nfa_postfix_dump(expr, FAIL);
#endif
-#ifdef DEBUG
nfa_regengine.expr = NULL;
-#endif
goto out;
}
@@ -7115,9 +7126,7 @@ nfa_regfree(prog)
if (prog != NULL)
{
vim_free(((nfa_regprog_T *)prog)->match_text);
-#ifdef DEBUG
vim_free(((nfa_regprog_T *)prog)->pattern);
-#endif
vim_free(prog);
}
}