changeset 5251:2e63b6c763f7 v7.4b.002

updated for version 7.4b.002 Problem: Crash searching for \%(\%(\|\d\|-\|\.\)*\|\*\). (Marcin Szamotulski) Also for \(\)*. Solution: Do add a state for opening parenthesis, so that we can check if it was added before at the same position.
author Bram Moolenaar <bram@vim.org>
date Thu, 01 Aug 2013 15:45:52 +0200
parents 71ba628fe723
children a41d03056478
files src/regexp_nfa.c src/testdir/test64.in src/testdir/test64.ok src/version.c
diffstat 4 files changed, 53 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -3910,15 +3910,27 @@ addstate(l, state, subs_arg, pim, off)
 	case NFA_ZCLOSE8:
 	case NFA_ZCLOSE9:
 #endif
+	case NFA_MOPEN:
 	case NFA_ZEND:
 	case NFA_SPLIT:
-	case NFA_NOPEN:
 	case NFA_SKIP_CHAR:
 	    /* These nodes are not added themselves but their "out" and/or
 	     * "out1" may be added below.  */
 	    break;
 
-	case NFA_MOPEN:
+	case NFA_BOL:
+	case NFA_BOF:
+	    /* "^" won't match past end-of-line, don't bother trying.
+	     * Except when at the end of the line, or when we are going to the
+	     * next line for a look-behind match. */
+	    if (reginput > regline
+		    && *reginput != NUL
+		    && (nfa_endp == NULL
+			|| !REG_MULTI
+			|| reglnum == nfa_endp->se_u.pos.lnum))
+		goto skip_add;
+	    /* FALLTHROUGH */
+
 	case NFA_MOPEN1:
 	case NFA_MOPEN2:
 	case NFA_MOPEN3:
@@ -3940,26 +3952,11 @@ addstate(l, state, subs_arg, pim, off)
 	case NFA_ZOPEN8:
 	case NFA_ZOPEN9:
 #endif
+	case NFA_NOPEN:
 	case NFA_ZSTART:
-	    /* These nodes do not need to be added, but we need to bail out
-	     * when it was tried to be added to this list before. */
-	    if (state->lastlist[nfa_ll_index] == l->id)
-		goto skip_add;
-	    state->lastlist[nfa_ll_index] = l->id;
-	    break;
-
-	case NFA_BOL:
-	case NFA_BOF:
-	    /* "^" won't match past end-of-line, don't bother trying.
-	     * Except when at the end of the line, or when we are going to the
-	     * next line for a look-behind match. */
-	    if (reginput > regline
-		    && *reginput != NUL
-		    && (nfa_endp == NULL
-			|| !REG_MULTI
-			|| reglnum == nfa_endp->se_u.pos.lnum))
-		goto skip_add;
-	    /* FALLTHROUGH */
+	    /* These nodes need to be added so that we can bail out when it
+	     * was added to this list before at the same position to avoid an
+	     * endless loop for "\(\)*" */
 
 	default:
 	    if (state->lastlist[nfa_ll_index] == l->id)
@@ -6025,13 +6022,41 @@ nfa_regmatch(prog, start, submatch, m)
 #endif
 		break;
 
+	    case NFA_MOPEN1:
+	    case NFA_MOPEN2:
+	    case NFA_MOPEN3:
+	    case NFA_MOPEN4:
+	    case NFA_MOPEN5:
+	    case NFA_MOPEN6:
+	    case NFA_MOPEN7:
+	    case NFA_MOPEN8:
+	    case NFA_MOPEN9:
+#ifdef FEAT_SYN_HL
+	    case NFA_ZOPEN:
+	    case NFA_ZOPEN1:
+	    case NFA_ZOPEN2:
+	    case NFA_ZOPEN3:
+	    case NFA_ZOPEN4:
+	    case NFA_ZOPEN5:
+	    case NFA_ZOPEN6:
+	    case NFA_ZOPEN7:
+	    case NFA_ZOPEN8:
+	    case NFA_ZOPEN9:
+#endif
+	    case NFA_NOPEN:
+	    case NFA_ZSTART:
+		/* These states are only added to be able to bail out when
+		 * they are added again, nothing is to be done. */
+		break;
+
 	    default:	/* regular character */
 	      {
 		int c = t->state->c;
 
-		/* TODO: put this in #ifdef later */
+#ifdef DEBUG
 		if (c < 0)
 		    EMSGN("INTERNAL: Negative state char: %ld", c);
+#endif
 		result = (c == curc);
 
 		if (!result && ireg_ic)
--- a/src/testdir/test64.in
+++ b/src/testdir/test64.in
@@ -340,6 +340,7 @@ STARTTEST
 :call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo bar '])
 :call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo xxx ', 'foo'])
 :call add(tl, [2, '[ ]\@!\p\%([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:'])
+:call add(tl, [2, '[ ]\@!\p\([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:', 's'])
 :call add(tl, [2, 'm\k\+_\@=\%(_\@!\k\)\@<=\k\+e', 'mx__xe', 'mx__xe'])
 :call add(tl, [2, '\%(\U\@<=S\k*\|S\l\)R', 'SuR', 'SuR'])
 :"
--- a/src/testdir/test64.ok
+++ b/src/testdir/test64.ok
@@ -776,6 +776,9 @@ OK 2 - ^\%(.*bar\)\@!.*\zsfoo
 OK 0 - [ ]\@!\p\%([ ]\@!\p\)*:
 OK 1 - [ ]\@!\p\%([ ]\@!\p\)*:
 OK 2 - [ ]\@!\p\%([ ]\@!\p\)*:
+OK 0 - [ ]\@!\p\([ ]\@!\p\)*:
+OK 1 - [ ]\@!\p\([ ]\@!\p\)*:
+OK 2 - [ ]\@!\p\([ ]\@!\p\)*:
 OK 0 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
 OK 1 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
 OK 2 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
--- a/src/version.c
+++ b/src/version.c
@@ -728,6 +728,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2,
+/**/
     1,
 /**/
     0