Karsten Hopp 1cb057
To: vim-dev@vim.org
Karsten Hopp 1cb057
Subject: Patch 7.2.307
Karsten Hopp 1cb057
Fcc: outbox
Karsten Hopp 1cb057
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 1cb057
Mime-Version: 1.0
Karsten Hopp 1cb057
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 1cb057
Content-Transfer-Encoding: 8bit
Karsten Hopp 1cb057
------------
Karsten Hopp 1cb057
Karsten Hopp 1cb057
Patch 7.2.307
Karsten Hopp 1cb057
Problem:    Crash with a very long syntax match statement. (Guy Gur Ari)
Karsten Hopp 1cb057
Solution:   When the offset does not fit in the two bytes available give an
Karsten Hopp 1cb057
            error instead of continuing with invalid pointers.
Karsten Hopp 1cb057
Files:      src/regexp.c
Karsten Hopp 1cb057
Karsten Hopp 1cb057
Karsten Hopp 1cb057
*** ../vim-7.2.306/src/regexp.c	2009-05-15 21:31:11.000000000 +0200
Karsten Hopp 1cb057
--- src/regexp.c	2009-11-25 18:13:03.000000000 +0100
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 583,588 ****
Karsten Hopp 1cb057
--- 583,589 ----
Karsten Hopp 1cb057
  #endif
Karsten Hopp 1cb057
  static char_u	*regcode;	/* Code-emit pointer, or JUST_CALC_SIZE */
Karsten Hopp 1cb057
  static long	regsize;	/* Code size. */
Karsten Hopp 1cb057
+ static int	reg_toolong;	/* TRUE when offset out of range */
Karsten Hopp 1cb057
  static char_u	had_endbrace[NSUBEXP];	/* flags, TRUE if end of () found */
Karsten Hopp 1cb057
  static unsigned	regflags;	/* RF_ flags for prog */
Karsten Hopp 1cb057
  static long	brace_min[10];	/* Minimums for complex brace repeats */
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 1028,1036 ****
Karsten Hopp 1cb057
      regcomp_start(expr, re_flags);
Karsten Hopp 1cb057
      regcode = r->program;
Karsten Hopp 1cb057
      regc(REGMAGIC);
Karsten Hopp 1cb057
!     if (reg(REG_NOPAREN, &flags) == NULL)
Karsten Hopp 1cb057
      {
Karsten Hopp 1cb057
  	vim_free(r);
Karsten Hopp 1cb057
  	return NULL;
Karsten Hopp 1cb057
      }
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
--- 1029,1039 ----
Karsten Hopp 1cb057
      regcomp_start(expr, re_flags);
Karsten Hopp 1cb057
      regcode = r->program;
Karsten Hopp 1cb057
      regc(REGMAGIC);
Karsten Hopp 1cb057
!     if (reg(REG_NOPAREN, &flags) == NULL || reg_toolong)
Karsten Hopp 1cb057
      {
Karsten Hopp 1cb057
  	vim_free(r);
Karsten Hopp 1cb057
+ 	if (reg_toolong)
Karsten Hopp 1cb057
+ 	    EMSG_RET_NULL(_("E339: Pattern too long"));
Karsten Hopp 1cb057
  	return NULL;
Karsten Hopp 1cb057
      }
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 1141,1146 ****
Karsten Hopp 1cb057
--- 1144,1150 ----
Karsten Hopp 1cb057
      re_has_z = 0;
Karsten Hopp 1cb057
  #endif
Karsten Hopp 1cb057
      regsize = 0L;
Karsten Hopp 1cb057
+     reg_toolong = FALSE;
Karsten Hopp 1cb057
      regflags = 0;
Karsten Hopp 1cb057
  #if defined(FEAT_SYN_HL) || defined(PROTO)
Karsten Hopp 1cb057
      had_eol = FALSE;
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 1228,1234 ****
Karsten Hopp 1cb057
      {
Karsten Hopp 1cb057
  	skipchr();
Karsten Hopp 1cb057
  	br = regbranch(&flags);
Karsten Hopp 1cb057
! 	if (br == NULL)
Karsten Hopp 1cb057
  	    return NULL;
Karsten Hopp 1cb057
  	regtail(ret, br);	/* BRANCH -> BRANCH. */
Karsten Hopp 1cb057
  	if (!(flags & HASWIDTH))
Karsten Hopp 1cb057
--- 1232,1238 ----
Karsten Hopp 1cb057
      {
Karsten Hopp 1cb057
  	skipchr();
Karsten Hopp 1cb057
  	br = regbranch(&flags);
Karsten Hopp 1cb057
! 	if (br == NULL || reg_toolong)
Karsten Hopp 1cb057
  	    return NULL;
Karsten Hopp 1cb057
  	regtail(ret, br);	/* BRANCH -> BRANCH. */
Karsten Hopp 1cb057
  	if (!(flags & HASWIDTH))
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 1313,1318 ****
Karsten Hopp 1cb057
--- 1317,1324 ----
Karsten Hopp 1cb057
  	    break;
Karsten Hopp 1cb057
  	skipchr();
Karsten Hopp 1cb057
  	regtail(latest, regnode(END)); /* operand ends */
Karsten Hopp 1cb057
+ 	if (reg_toolong)
Karsten Hopp 1cb057
+ 	    break;
Karsten Hopp 1cb057
  	reginsert(MATCH, latest);
Karsten Hopp 1cb057
  	chain = latest;
Karsten Hopp 1cb057
      }
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 1382,1388 ****
Karsten Hopp 1cb057
  			    break;
Karsten Hopp 1cb057
  	    default:
Karsten Hopp 1cb057
  			    latest = regpiece(&flags);
Karsten Hopp 1cb057
! 			    if (latest == NULL)
Karsten Hopp 1cb057
  				return NULL;
Karsten Hopp 1cb057
  			    *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
Karsten Hopp 1cb057
  			    if (chain == NULL)	/* First piece. */
Karsten Hopp 1cb057
--- 1388,1394 ----
Karsten Hopp 1cb057
  			    break;
Karsten Hopp 1cb057
  	    default:
Karsten Hopp 1cb057
  			    latest = regpiece(&flags);
Karsten Hopp 1cb057
! 			    if (latest == NULL || reg_toolong)
Karsten Hopp 1cb057
  				return NULL;
Karsten Hopp 1cb057
  			    *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
Karsten Hopp 1cb057
  			    if (chain == NULL)	/* First piece. */
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 2540,2547 ****
Karsten Hopp 1cb057
  	offset = (int)(scan - val);
Karsten Hopp 1cb057
      else
Karsten Hopp 1cb057
  	offset = (int)(val - scan);
Karsten Hopp 1cb057
!     *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
Karsten Hopp 1cb057
!     *(scan + 2) = (char_u) (offset & 0377);
Karsten Hopp 1cb057
  }
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
  /*
Karsten Hopp 1cb057
--- 2546,2561 ----
Karsten Hopp 1cb057
  	offset = (int)(scan - val);
Karsten Hopp 1cb057
      else
Karsten Hopp 1cb057
  	offset = (int)(val - scan);
Karsten Hopp 1cb057
!     /* When the offset uses more than 16 bits it can no longer fit in the two
Karsten Hopp 1cb057
!      * bytes avaliable.  Use a global flag to avoid having to check return
Karsten Hopp 1cb057
!      * values in too many places. */
Karsten Hopp 1cb057
!     if (offset > 0xffff)
Karsten Hopp 1cb057
! 	reg_toolong = TRUE;
Karsten Hopp 1cb057
!     else
Karsten Hopp 1cb057
!     {
Karsten Hopp 1cb057
! 	*(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
Karsten Hopp 1cb057
! 	*(scan + 2) = (char_u) (offset & 0377);
Karsten Hopp 1cb057
!     }
Karsten Hopp 1cb057
  }
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
  /*
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 5764,5769 ****
Karsten Hopp 1cb057
--- 5778,5785 ----
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
  /*
Karsten Hopp 1cb057
   * regnext - dig the "next" pointer out of a node
Karsten Hopp 1cb057
+  * Returns NULL when calculating size, when there is no next item and when
Karsten Hopp 1cb057
+  * there is an error.
Karsten Hopp 1cb057
   */
Karsten Hopp 1cb057
      static char_u *
Karsten Hopp 1cb057
  regnext(p)
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 5771,5777 ****
Karsten Hopp 1cb057
  {
Karsten Hopp 1cb057
      int	    offset;
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
!     if (p == JUST_CALC_SIZE)
Karsten Hopp 1cb057
  	return NULL;
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
      offset = NEXT(p);
Karsten Hopp 1cb057
--- 5787,5793 ----
Karsten Hopp 1cb057
  {
Karsten Hopp 1cb057
      int	    offset;
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
!     if (p == JUST_CALC_SIZE || reg_toolong)
Karsten Hopp 1cb057
  	return NULL;
Karsten Hopp 1cb057
  
Karsten Hopp 1cb057
      offset = NEXT(p);
Karsten Hopp 1cb057
*** ../vim-7.2.306/src/version.c	2009-11-25 17:15:16.000000000 +0100
Karsten Hopp 1cb057
--- src/version.c	2009-11-25 18:14:32.000000000 +0100
Karsten Hopp 1cb057
***************
Karsten Hopp 1cb057
*** 683,684 ****
Karsten Hopp 1cb057
--- 683,686 ----
Karsten Hopp 1cb057
  {   /* Add new patch number below this line */
Karsten Hopp 1cb057
+ /**/
Karsten Hopp 1cb057
+     307,
Karsten Hopp 1cb057
  /**/
Karsten Hopp 1cb057
Karsten Hopp 1cb057
-- 
Karsten Hopp 1cb057
The fastest way to get an engineer to solve a problem is to declare that the
Karsten Hopp 1cb057
problem is unsolvable.  No engineer can walk away from an unsolvable problem
Karsten Hopp 1cb057
until it's solved.
Karsten Hopp 1cb057
				(Scott Adams - The Dilbert principle)
Karsten Hopp 1cb057
Karsten Hopp 1cb057
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 1cb057
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 1cb057
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp 1cb057
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///