changeset 2010:bec979a53f47 v7.2.307

updated for version 7.2-307
author vimboss
date Wed, 25 Nov 2009 17:21:32 +0000
parents c5a806b29372
children a3a4be6bdcdd
files src/regexp.c src/version.c
diffstat 2 files changed, 24 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -583,6 +583,7 @@ static int	re_has_z;	/* \z item detected
 #endif
 static char_u	*regcode;	/* Code-emit pointer, or JUST_CALC_SIZE */
 static long	regsize;	/* Code size. */
+static int	reg_toolong;	/* TRUE when offset out of range */
 static char_u	had_endbrace[NSUBEXP];	/* flags, TRUE if end of () found */
 static unsigned	regflags;	/* RF_ flags for prog */
 static long	brace_min[10];	/* Minimums for complex brace repeats */
@@ -1028,9 +1029,11 @@ vim_regcomp(expr, re_flags)
     regcomp_start(expr, re_flags);
     regcode = r->program;
     regc(REGMAGIC);
-    if (reg(REG_NOPAREN, &flags) == NULL)
+    if (reg(REG_NOPAREN, &flags) == NULL || reg_toolong)
     {
 	vim_free(r);
+	if (reg_toolong)
+	    EMSG_RET_NULL(_("E339: Pattern too long"));
 	return NULL;
     }
 
@@ -1141,6 +1144,7 @@ regcomp_start(expr, re_flags)
     re_has_z = 0;
 #endif
     regsize = 0L;
+    reg_toolong = FALSE;
     regflags = 0;
 #if defined(FEAT_SYN_HL) || defined(PROTO)
     had_eol = FALSE;
@@ -1228,7 +1232,7 @@ reg(paren, flagp)
     {
 	skipchr();
 	br = regbranch(&flags);
-	if (br == NULL)
+	if (br == NULL || reg_toolong)
 	    return NULL;
 	regtail(ret, br);	/* BRANCH -> BRANCH. */
 	if (!(flags & HASWIDTH))
@@ -1313,6 +1317,8 @@ regbranch(flagp)
 	    break;
 	skipchr();
 	regtail(latest, regnode(END)); /* operand ends */
+	if (reg_toolong)
+	    break;
 	reginsert(MATCH, latest);
 	chain = latest;
     }
@@ -1382,7 +1388,7 @@ regconcat(flagp)
 			    break;
 	    default:
 			    latest = regpiece(&flags);
-			    if (latest == NULL)
+			    if (latest == NULL || reg_toolong)
 				return NULL;
 			    *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
 			    if (chain == NULL)	/* First piece. */
@@ -2540,8 +2546,16 @@ regtail(p, val)
 	offset = (int)(scan - val);
     else
 	offset = (int)(val - scan);
-    *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
-    *(scan + 2) = (char_u) (offset & 0377);
+    /* When the offset uses more than 16 bits it can no longer fit in the two
+     * bytes avaliable.  Use a global flag to avoid having to check return
+     * values in too many places. */
+    if (offset > 0xffff)
+	reg_toolong = TRUE;
+    else
+    {
+	*(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
+	*(scan + 2) = (char_u) (offset & 0377);
+    }
 }
 
 /*
@@ -5764,6 +5778,8 @@ do_class:
 
 /*
  * regnext - dig the "next" pointer out of a node
+ * Returns NULL when calculating size, when there is no next item and when
+ * there is an error.
  */
     static char_u *
 regnext(p)
@@ -5771,7 +5787,7 @@ regnext(p)
 {
     int	    offset;
 
-    if (p == JUST_CALC_SIZE)
+    if (p == JUST_CALC_SIZE || reg_toolong)
 	return NULL;
 
     offset = NEXT(p);
--- a/src/version.c
+++ b/src/version.c
@@ -682,6 +682,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    307,
+/**/
     306,
 /**/
     305,