I just tried the file. Opening Vim took about a minute with Vim
running at 100% CPU after which Vim became responsive. I then scrolled
down by repeating 99<PageDown> and just before I reached the bitmap
part of the XPM file Vim crashed. I've tried a few times and it
crashes every time, but only after reaching the bitmap part.

There are way too many syntax groups, and they overflow into syntax
clusters, because clusters are stored in a high part of the syntax group
id number-space, and Vim doesn't check it.

The attached preliminary patch puts in a check for this and a couple of
other possible syntax overflow conditions, so we should get errors, not
crashes.

It fixes this particular problem for me. An error occurs when the file
is loaded, and scrolling is slow, but doesn't crash, and can be
interrupted with control-C.

Can others test this and confirm?

Bram, if you're happy with this approach, I can tidy up the patch a bit,
i.e. put in error message numbers, including in the documentation, if
that's helpful.

Ben.



-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
# HG changeset patch
# Parent c9bc095adaae71c79d2382c27601390ae2008201
diff --git a/src/syntax.c b/src/syntax.c
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -229,6 +229,7 @@
 #define SYNID_TOP	15000	    /* syntax group ID for contains=TOP */
 #define SYNID_CONTAINED	20000	    /* syntax group ID for contains=CONTAINED */
 #define SYNID_CLUSTER	25000	    /* first syntax group ID for clusters */
+#define MAX_SYN_INC_TAG	4999	    /* maximum before the above overflow */
 
 /*
  * Annoying Hack(TM):  ":syn include" needs this pointer to pass to
@@ -4661,6 +4662,11 @@
 	    return;
 	}
 	sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+	if (sgl_id == 0)
+	{
+	    EMSG((char_u *)_("Exxx: Too many syntax clusters"));
+	    return;
+	}
 	/* separate_nextcmd() and expand_filename() depend on this */
 	eap->arg = rest;
     }
@@ -4689,6 +4695,11 @@
      * Save and restore the existing top-level grouplist id and ":syn
      * include" tag around the actual inclusion.
      */
+    if (running_syn_inc_tag >= MAX_SYN_INC_TAG)
+    {
+	EMSG((char_u *)_("Exxx: Too many syntax includes"));
+	return;
+    }
     prev_syn_inc_tag = current_syn_inc_tag;
     current_syn_inc_tag = ++running_syn_inc_tag;
     prev_toplvl_grp = curwin->w_s->b_syn_topgrp;
@@ -4725,8 +4736,18 @@
     {
 	syn_id = syn_check_group(arg, (int)(group_name_end - arg));
 
-	/* allocate a buffer, for removing the backslashes in the keyword */
-	keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
+	if (syn_id == 0)
+	{
+	    /* if we can't create the syntax group, don't allocate a buffer so
+	     * that we fail */
+	    keyword_copy = NULL;
+	}
+	else
+	{
+	    /* allocate a buffer, for removing the backslashes in the keyword */
+	    keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
+	}
+
 	if (keyword_copy != NULL)
 	{
 	    syn_opt_arg.flags = 0;
@@ -5426,6 +5447,14 @@
 	curwin->w_s->b_syn_clusters.ga_growsize = 10;
     }
 
+    /* Fail if syntax group IDs overflow */
+    len = curwin->w_s->b_syn_clusters.ga_len;
+    if (len + SYNID_CLUSTER < SYNID_CLUSTER)
+    {
+	vim_free(name);
+	return 0;
+    }
+
     /*
      * Make room for at least one other cluster entry.
      */
@@ -5476,41 +5505,48 @@
 
     if (rest != NULL)
     {
-	scl_id = syn_check_cluster(arg, (int)(group_name_end - arg))
-							      - SYNID_CLUSTER;
-
-	for (;;)
-	{
-	    if (STRNICMP(rest, "add", 3) == 0
-		    && (vim_iswhite(rest[3]) || rest[3] == '='))
-	    {
-		opt_len = 3;
-		list_op = CLUSTER_ADD;
-	    }
-	    else if (STRNICMP(rest, "remove", 6) == 0
-		    && (vim_iswhite(rest[6]) || rest[6] == '='))
-	    {
-		opt_len = 6;
-		list_op = CLUSTER_SUBTRACT;
-	    }
-	    else if (STRNICMP(rest, "contains", 8) == 0
-			&& (vim_iswhite(rest[8]) || rest[8] == '='))
-	    {
-		opt_len = 8;
-		list_op = CLUSTER_REPLACE;
-	    }
-	    else
-		break;
-
-	    clstr_list = NULL;
-	    if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
-	    {
-		EMSG2(_(e_invarg2), rest);
-		break;
-	    }
-	    syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
-			     &clstr_list, list_op);
-	    got_clstr = TRUE;
+	scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+
+	if (scl_id == 0)
+	{
+	    EMSG((char_u *)_("Exxx: Too many syntax clusters"));
+	}
+	else
+	{
+	    scl_id -= SYNID_CLUSTER;
+	    for (;;)
+	    {
+	    	if (STRNICMP(rest, "add", 3) == 0
+		    	&& (vim_iswhite(rest[3]) || rest[3] == '='))
+	    	{
+		    opt_len = 3;
+		    list_op = CLUSTER_ADD;
+	    	}
+	    	else if (STRNICMP(rest, "remove", 6) == 0
+		    	&& (vim_iswhite(rest[6]) || rest[6] == '='))
+	    	{
+		    opt_len = 6;
+		    list_op = CLUSTER_SUBTRACT;
+	    	}
+	    	else if (STRNICMP(rest, "contains", 8) == 0
+			    && (vim_iswhite(rest[8]) || rest[8] == '='))
+	    	{
+		    opt_len = 8;
+		    list_op = CLUSTER_REPLACE;
+	    	}
+	    	else
+		    break;
+
+	    	clstr_list = NULL;
+	    	if (get_id_list(&rest, opt_len, &clstr_list) == FAIL)
+	    	{
+		    EMSG2(_(e_invarg2), rest);
+		    break;
+	    	}
+	    	syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
+			     	 &clstr_list, list_op);
+	    	got_clstr = TRUE;
+	    }
 	}
 
 	if (got_clstr)
@@ -8973,6 +9009,13 @@
 	highlight_ga.ga_growsize = 10;
     }
 
+    if (highlight_ga.ga_len >= SYNID_ALLBUT)
+    {
+	EMSG(_("Exxx: Too many syntax groups"));
+	vim_free(name);
+	return 0;
+    }
+
     /*
      * Make room for at least one other syntax_highlight entry.
      */

Raspunde prin e-mail lui