diff --git a/7.2.307 b/7.2.307 new file mode 100644 index 0000000..23504e2 --- /dev/null +++ b/7.2.307 @@ -0,0 +1,181 @@ +To: vim-dev@vim.org +Subject: Patch 7.2.307 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.2.307 +Problem: Crash with a very long syntax match statement. (Guy Gur Ari) +Solution: When the offset does not fit in the two bytes available give an + error instead of continuing with invalid pointers. +Files: src/regexp.c + + +*** ../vim-7.2.306/src/regexp.c 2009-05-15 21:31:11.000000000 +0200 +--- src/regexp.c 2009-11-25 18:13:03.000000000 +0100 +*************** +*** 583,588 **** +--- 583,589 ---- + #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,1036 **** + regcomp_start(expr, re_flags); + regcode = r->program; + regc(REGMAGIC); +! if (reg(REG_NOPAREN, &flags) == NULL) + { + vim_free(r); + return NULL; + } + +--- 1029,1039 ---- + regcomp_start(expr, re_flags); + regcode = r->program; + regc(REGMAGIC); +! if (reg(REG_NOPAREN, &flags) == NULL || reg_toolong) + { + vim_free(r); ++ if (reg_toolong) ++ EMSG_RET_NULL(_("E339: Pattern too long")); + return NULL; + } + +*************** +*** 1141,1146 **** +--- 1144,1150 ---- + re_has_z = 0; + #endif + regsize = 0L; ++ reg_toolong = FALSE; + regflags = 0; + #if defined(FEAT_SYN_HL) || defined(PROTO) + had_eol = FALSE; +*************** +*** 1228,1234 **** + { + skipchr(); + br = regbranch(&flags); +! if (br == NULL) + return NULL; + regtail(ret, br); /* BRANCH -> BRANCH. */ + if (!(flags & HASWIDTH)) +--- 1232,1238 ---- + { + skipchr(); + br = regbranch(&flags); +! if (br == NULL || reg_toolong) + return NULL; + regtail(ret, br); /* BRANCH -> BRANCH. */ + if (!(flags & HASWIDTH)) +*************** +*** 1313,1318 **** +--- 1317,1324 ---- + break; + skipchr(); + regtail(latest, regnode(END)); /* operand ends */ ++ if (reg_toolong) ++ break; + reginsert(MATCH, latest); + chain = latest; + } +*************** +*** 1382,1388 **** + break; + default: + latest = regpiece(&flags); +! if (latest == NULL) + return NULL; + *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH); + if (chain == NULL) /* First piece. */ +--- 1388,1394 ---- + break; + default: + latest = regpiece(&flags); +! if (latest == NULL || reg_toolong) + return NULL; + *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH); + if (chain == NULL) /* First piece. */ +*************** +*** 2540,2547 **** + offset = (int)(scan - val); + else + offset = (int)(val - scan); +! *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377); +! *(scan + 2) = (char_u) (offset & 0377); + } + + /* +--- 2546,2561 ---- + offset = (int)(scan - val); + else + offset = (int)(val - scan); +! /* 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,5769 **** +--- 5778,5785 ---- + + /* + * 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,5777 **** + { + int offset; + +! if (p == JUST_CALC_SIZE) + return NULL; + + offset = NEXT(p); +--- 5787,5793 ---- + { + int offset; + +! if (p == JUST_CALC_SIZE || reg_toolong) + return NULL; + + offset = NEXT(p); +*** ../vim-7.2.306/src/version.c 2009-11-25 17:15:16.000000000 +0100 +--- src/version.c 2009-11-25 18:14:32.000000000 +0100 +*************** +*** 683,684 **** +--- 683,686 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 307, + /**/ + +-- +The fastest way to get an engineer to solve a problem is to declare that the +problem is unsolvable. No engineer can walk away from an unsolvable problem +until it's solved. + (Scott Adams - The Dilbert principle) + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ download, build and distribute -- http://www.A-A-P.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///