components/vim/vim72-patches/7.2.307
changeset 198 172fc01ce997
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/vim/vim72-patches/7.2.307	Thu Apr 07 16:25:07 2011 -0700
@@ -0,0 +1,181 @@
+To: [email protected]
+Subject: Patch 7.2.307
+Fcc: outbox
+From: Bram Moolenaar <[email protected]>
+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 -- [email protected] -- 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    ///