]> granicus.if.org Git - vim/commitdiff
updated for version 7.2-307 v7.2.307
authorBram Moolenaar <Bram@vim.org>
Wed, 25 Nov 2009 17:21:32 +0000 (17:21 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 25 Nov 2009 17:21:32 +0000 (17:21 +0000)
src/regexp.c
src/version.c

index dc0433dbf8beac301766d33e3c94101e61be5e49..9ce4cd8f8f7f1d5d24d33775e4b29461649c3031 100644 (file)
@@ -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);
index 24d73f422b5f61b3999fbcbf464a7a172ae6d695..0748170ee843a28316c5e4facd29f76803860350 100644 (file)
@@ -681,6 +681,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    307,
 /**/
     306,
 /**/