Karsten Hopp 9bf194
To: vim_dev@googlegroups.com
Karsten Hopp 9bf194
Subject: Patch 7.3.148
Karsten Hopp 9bf194
Fcc: outbox
Karsten Hopp 9bf194
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 9bf194
Mime-Version: 1.0
Karsten Hopp 9bf194
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 9bf194
Content-Transfer-Encoding: 8bit
Karsten Hopp 9bf194
------------
Karsten Hopp 9bf194
Karsten Hopp 9bf194
Patch 7.3.148
Karsten Hopp 9bf194
Problem:    A syntax file with a huge number of items or clusters causes weird
Karsten Hopp 9bf194
	    behavior, a hang or a crash. (Yukihiro Nakadaira)
Karsten Hopp 9bf194
Solution:   Check running out of IDs. (partly by Ben Schmidt)
Karsten Hopp 9bf194
Files:	    src/syntax.c
Karsten Hopp 9bf194
Karsten Hopp 9bf194
Karsten Hopp 9bf194
*** ../vim-7.3.147/src/syntax.c	2011-01-22 00:58:15.000000000 +0100
Karsten Hopp 9bf194
--- src/syntax.c	2011-04-01 14:25:39.000000000 +0200
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 219,234 ****
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  /*
Karsten Hopp 9bf194
   * Syntax group IDs have different types:
Karsten Hopp 9bf194
!  *     0 -  9999  normal syntax groups
Karsten Hopp 9bf194
!  * 10000 - 14999  ALLBUT indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * 15000 - 19999  TOP indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * 20000 - 24999  CONTAINED indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * >= 25000	  cluster IDs (subtract SYNID_CLUSTER for the cluster ID)
Karsten Hopp 9bf194
!  */
Karsten Hopp 9bf194
! #define SYNID_ALLBUT	10000	    /* syntax group ID for contains=ALLBUT */
Karsten Hopp 9bf194
! #define SYNID_TOP	15000	    /* syntax group ID for contains=TOP */
Karsten Hopp 9bf194
! #define SYNID_CONTAINED	20000	    /* syntax group ID for contains=CONTAINED */
Karsten Hopp 9bf194
! #define SYNID_CLUSTER	25000	    /* first syntax group ID for clusters */
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  /*
Karsten Hopp 9bf194
   * Annoying Hack(TM):  ":syn include" needs this pointer to pass to
Karsten Hopp 9bf194
--- 219,238 ----
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  /*
Karsten Hopp 9bf194
   * Syntax group IDs have different types:
Karsten Hopp 9bf194
!  *     0 - 19999  normal syntax groups
Karsten Hopp 9bf194
!  * 20000 - 20999  ALLBUT indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * 21000 - 21999  TOP indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * 22000 - 22999  CONTAINED indicator (current_syn_inc_tag added)
Karsten Hopp 9bf194
!  * 23000 - 32767  cluster IDs (subtract SYNID_CLUSTER for the cluster ID)
Karsten Hopp 9bf194
!  */
Karsten Hopp 9bf194
! #define SYNID_ALLBUT	20000	    /* syntax group ID for contains=ALLBUT */
Karsten Hopp 9bf194
! #define SYNID_TOP	21000	    /* syntax group ID for contains=TOP */
Karsten Hopp 9bf194
! #define SYNID_CONTAINED	22000	    /* syntax group ID for contains=CONTAINED */
Karsten Hopp 9bf194
! #define SYNID_CLUSTER	23000	    /* first syntax group ID for clusters */
Karsten Hopp 9bf194
! 
Karsten Hopp 9bf194
! #define MAX_SYNID       SYNID_ALLBUT
Karsten Hopp 9bf194
! #define MAX_SYN_INC_TAG	999	    /* maximum before the above overflow */
Karsten Hopp 9bf194
! #define MAX_CLUSTER_ID  (32767 - SYNID_CLUSTER)
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  /*
Karsten Hopp 9bf194
   * Annoying Hack(TM):  ":syn include" needs this pointer to pass to
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 3442,3447 ****
Karsten Hopp 9bf194
--- 3446,3454 ----
Karsten Hopp 9bf194
      /* free the stored states */
Karsten Hopp 9bf194
      syn_stack_free_all(block);
Karsten Hopp 9bf194
      invalidate_current_state();
Karsten Hopp 9bf194
+ 
Karsten Hopp 9bf194
+     /* Reset the counter for ":syn include" */
Karsten Hopp 9bf194
+     running_syn_inc_tag = 0;
Karsten Hopp 9bf194
  }
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  /*
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 4661,4666 ****
Karsten Hopp 9bf194
--- 4668,4675 ----
Karsten Hopp 9bf194
  	    return;
Karsten Hopp 9bf194
  	}
Karsten Hopp 9bf194
  	sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
Karsten Hopp 9bf194
+ 	if (sgl_id == 0)
Karsten Hopp 9bf194
+ 	    return;
Karsten Hopp 9bf194
  	/* separate_nextcmd() and expand_filename() depend on this */
Karsten Hopp 9bf194
  	eap->arg = rest;
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 4689,4694 ****
Karsten Hopp 9bf194
--- 4698,4708 ----
Karsten Hopp 9bf194
       * Save and restore the existing top-level grouplist id and ":syn
Karsten Hopp 9bf194
       * include" tag around the actual inclusion.
Karsten Hopp 9bf194
       */
Karsten Hopp 9bf194
+     if (running_syn_inc_tag >= MAX_SYN_INC_TAG)
Karsten Hopp 9bf194
+     {
Karsten Hopp 9bf194
+ 	EMSG((char_u *)_("E847: Too many syntax includes"));
Karsten Hopp 9bf194
+ 	return;
Karsten Hopp 9bf194
+     }
Karsten Hopp 9bf194
      prev_syn_inc_tag = current_syn_inc_tag;
Karsten Hopp 9bf194
      current_syn_inc_tag = ++running_syn_inc_tag;
Karsten Hopp 9bf194
      prev_toplvl_grp = curwin->w_s->b_syn_topgrp;
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 4712,4718 ****
Karsten Hopp 9bf194
      char_u	*group_name_end;
Karsten Hopp 9bf194
      int		syn_id;
Karsten Hopp 9bf194
      char_u	*rest;
Karsten Hopp 9bf194
!     char_u	*keyword_copy;
Karsten Hopp 9bf194
      char_u	*p;
Karsten Hopp 9bf194
      char_u	*kw;
Karsten Hopp 9bf194
      syn_opt_arg_T syn_opt_arg;
Karsten Hopp 9bf194
--- 4726,4732 ----
Karsten Hopp 9bf194
      char_u	*group_name_end;
Karsten Hopp 9bf194
      int		syn_id;
Karsten Hopp 9bf194
      char_u	*rest;
Karsten Hopp 9bf194
!     char_u	*keyword_copy = NULL;
Karsten Hopp 9bf194
      char_u	*p;
Karsten Hopp 9bf194
      char_u	*kw;
Karsten Hopp 9bf194
      syn_opt_arg_T syn_opt_arg;
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 4724,4732 ****
Karsten Hopp 9bf194
      if (rest != NULL)
Karsten Hopp 9bf194
      {
Karsten Hopp 9bf194
  	syn_id = syn_check_group(arg, (int)(group_name_end - arg));
Karsten Hopp 9bf194
! 
Karsten Hopp 9bf194
! 	/* allocate a buffer, for removing the backslashes in the keyword */
Karsten Hopp 9bf194
! 	keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
Karsten Hopp 9bf194
  	if (keyword_copy != NULL)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
  	    syn_opt_arg.flags = 0;
Karsten Hopp 9bf194
--- 4738,4746 ----
Karsten Hopp 9bf194
      if (rest != NULL)
Karsten Hopp 9bf194
      {
Karsten Hopp 9bf194
  	syn_id = syn_check_group(arg, (int)(group_name_end - arg));
Karsten Hopp 9bf194
! 	if (syn_id != 0)
Karsten Hopp 9bf194
! 	    /* allocate a buffer, for removing backslashes in the keyword */
Karsten Hopp 9bf194
! 	    keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
Karsten Hopp 9bf194
  	if (keyword_copy != NULL)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
  	    syn_opt_arg.flags = 0;
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 5133,5139 ****
Karsten Hopp 9bf194
  			    (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_flags |= syn_opt_arg.flags;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
Karsten Hopp 9bf194
! 		    SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag = current_syn_inc_tag;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_syn_match_id =
Karsten Hopp 9bf194
  							ppp->pp_matchgroup_id;
Karsten Hopp 9bf194
  #ifdef FEAT_CONCEAL
Karsten Hopp 9bf194
--- 5147,5154 ----
Karsten Hopp 9bf194
  			    (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_flags |= syn_opt_arg.flags;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
Karsten Hopp 9bf194
! 		    SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag =
Karsten Hopp 9bf194
! 							  current_syn_inc_tag;
Karsten Hopp 9bf194
  		    SYN_ITEMS(curwin->w_s)[idx].sp_syn_match_id =
Karsten Hopp 9bf194
  							ppp->pp_matchgroup_id;
Karsten Hopp 9bf194
  #ifdef FEAT_CONCEAL
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 5426,5431 ****
Karsten Hopp 9bf194
--- 5441,5454 ----
Karsten Hopp 9bf194
  	curwin->w_s->b_syn_clusters.ga_growsize = 10;
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
+     len = curwin->w_s->b_syn_clusters.ga_len;
Karsten Hopp 9bf194
+     if (len >= MAX_CLUSTER_ID)
Karsten Hopp 9bf194
+     {
Karsten Hopp 9bf194
+ 	EMSG((char_u *)_("E848: Too many syntax clusters"));
Karsten Hopp 9bf194
+ 	vim_free(name);
Karsten Hopp 9bf194
+ 	return 0;
Karsten Hopp 9bf194
+     }
Karsten Hopp 9bf194
+ 
Karsten Hopp 9bf194
      /*
Karsten Hopp 9bf194
       * Make room for at least one other cluster entry.
Karsten Hopp 9bf194
       */
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 5434,5440 ****
Karsten Hopp 9bf194
  	vim_free(name);
Karsten Hopp 9bf194
  	return 0;
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
-     len = curwin->w_s->b_syn_clusters.ga_len;
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
      vim_memset(&(SYN_CLSTR(curwin->w_s)[len]), 0, sizeof(syn_cluster_T));
Karsten Hopp 9bf194
      SYN_CLSTR(curwin->w_s)[len].scl_name = name;
Karsten Hopp 9bf194
--- 5457,5462 ----
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 5476,5483 ****
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
      if (rest != NULL)
Karsten Hopp 9bf194
      {
Karsten Hopp 9bf194
! 	scl_id = syn_check_cluster(arg, (int)(group_name_end - arg))
Karsten Hopp 9bf194
! 							      - SYNID_CLUSTER;
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  	for (;;)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
--- 5498,5507 ----
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
      if (rest != NULL)
Karsten Hopp 9bf194
      {
Karsten Hopp 9bf194
! 	scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
Karsten Hopp 9bf194
! 	if (scl_id == 0)
Karsten Hopp 9bf194
! 	    return;
Karsten Hopp 9bf194
! 	scl_id -= SYNID_CLUSTER;
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
  	for (;;)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 5516,5522 ****
Karsten Hopp 9bf194
  	if (got_clstr)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
  	    redraw_curbuf_later(SOME_VALID);
Karsten Hopp 9bf194
! 	    syn_stack_free_all(curwin->w_s);	/* Need to recompute all syntax. */
Karsten Hopp 9bf194
  	}
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
--- 5540,5546 ----
Karsten Hopp 9bf194
  	if (got_clstr)
Karsten Hopp 9bf194
  	{
Karsten Hopp 9bf194
  	    redraw_curbuf_later(SOME_VALID);
Karsten Hopp 9bf194
! 	    syn_stack_free_all(curwin->w_s);	/* Need to recompute all. */
Karsten Hopp 9bf194
  	}
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 8972,8977 ****
Karsten Hopp 9bf194
--- 8996,9008 ----
Karsten Hopp 9bf194
  	highlight_ga.ga_growsize = 10;
Karsten Hopp 9bf194
      }
Karsten Hopp 9bf194
  
Karsten Hopp 9bf194
+     if (highlight_ga.ga_len >= MAX_SYNID)
Karsten Hopp 9bf194
+     {
Karsten Hopp 9bf194
+ 	EMSG(_("E849: Too many syntax groups"));
Karsten Hopp 9bf194
+ 	vim_free(name);
Karsten Hopp 9bf194
+ 	return 0;
Karsten Hopp 9bf194
+     }
Karsten Hopp 9bf194
+ 
Karsten Hopp 9bf194
      /*
Karsten Hopp 9bf194
       * Make room for at least one other syntax_highlight entry.
Karsten Hopp 9bf194
       */
Karsten Hopp 9bf194
*** ../vim-7.3.147/src/version.c	2011-04-01 13:05:37.000000000 +0200
Karsten Hopp 9bf194
--- src/version.c	2011-04-01 14:26:44.000000000 +0200
Karsten Hopp 9bf194
***************
Karsten Hopp 9bf194
*** 716,717 ****
Karsten Hopp 9bf194
--- 716,719 ----
Karsten Hopp 9bf194
  {   /* Add new patch number below this line */
Karsten Hopp 9bf194
+ /**/
Karsten Hopp 9bf194
+     148,
Karsten Hopp 9bf194
  /**/
Karsten Hopp 9bf194
Karsten Hopp 9bf194
-- 
Karsten Hopp 9bf194
BLACK KNIGHT: None shall pass.
Karsten Hopp 9bf194
ARTHUR:       I have no quarrel with you, brave Sir knight, but I must cross
Karsten Hopp 9bf194
              this bridge.
Karsten Hopp 9bf194
BLACK KNIGHT: Then you shall die.
Karsten Hopp 9bf194
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp 9bf194
Karsten Hopp 9bf194
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 9bf194
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 9bf194
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 9bf194
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///