[PATCH] Fix for segfault on large syntax file



Hi,

this pach fixes segfaulting on syntax files with more than
1024 keywords per context (and possibly with more than
128 contexts). These numbers were harcoded and now they grow
as the alloced number does not suffice.

This fixes a bug number #3829 in MC bug tracking system.

Motto: "1024 will be enough for everyone forever"


David
diff -S ChangeLog -X .diffignore -urNp mc/edit/ChangeLog mc-large-syntax/edit/ChangeLog
--- mc/edit/ChangeLog	Tue Jun 10 18:59:53 2003
+++ mc-large-syntax/edit/ChangeLog	Fri Jun 13 19:13:32 2003
@@ -0,0 +1,6 @@
+2003-06-13  David Sterba  <dave jikos cz>
+
+	* syntax.c (edit_read_syntax_rules): Dynamically allocate
+	more space for contexts and for words in context. Fixes segfault
+	on syntax files with more than 1024 keywords in a context.
+
diff -S ChangeLog -X .diffignore -urNp mc/edit/syntax.c mc-large-syntax/edit/syntax.c
--- mc/edit/syntax.c	Thu Mar  6 19:42:33 2003
+++ mc-large-syntax/edit/syntax.c	Fri Jun 13 19:17:40 2003
@@ -648,13 +648,16 @@ edit_read_syntax_rules (WEdit *edit, FIL
     int num_words = -1, num_contexts = -1;
     int argc, result = 0;
     int i, j;
+    int alloc_contexts = MAX_CONTEXTS,
+    	alloc_words_per_context = MAX_WORDS_PER_CONTEXT,
+	max_alloc_words_per_context = MAX_WORDS_PER_CONTEXT;
 
     args[0] = 0;
 
     strcpy (whole_left, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
     strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
 
-    r = edit->rules = g_malloc0 (MAX_CONTEXTS * sizeof (struct context_rule *));
+    r = edit->rules = g_malloc0 (alloc_contexts * sizeof (struct context_rule *));
 
     if (!defines)
 	defines = g_tree_new ((GCompareFunc) strcmp);
@@ -760,10 +763,7 @@ edit_read_syntax_rules (WEdit *edit, FIL
 		c->first_left = *c->left;
 		c->first_right = *c->right;
 	    }
-	    c->keyword = g_malloc0 (MAX_WORDS_PER_CONTEXT * sizeof (struct key_word *));
-#if 0
-	    c->max_words = MAX_WORDS_PER_CONTEXT;
-#endif
+	    c->keyword = g_malloc0 (alloc_words_per_context * sizeof (struct key_word *));
 	    num_words = 1;
 	    c->keyword[0] = g_malloc0 (sizeof (struct key_word));
 	    subst_defines (defines, a, &args[1024]);
@@ -780,7 +780,15 @@ edit_read_syntax_rules (WEdit *edit, FIL
 	    c->keyword[0]->color = this_try_alloc_color_pair (fg, bg);
 	    c->keyword[0]->keyword = g_strdup (" ");
 	    check_not_a;
-	    num_contexts++;
+
+	    alloc_words_per_context = MAX_WORDS_PER_CONTEXT;
+	    if (num_contexts++ > alloc_contexts) {
+	    	struct context_rule **tmp;
+
+		alloc_contexts += 128;
+		tmp = g_realloc (r, alloc_contexts * sizeof (struct context_rule *));
+		r = tmp;
+	    }
 	} else if (!strcmp (args[0], "spellcheck")) {
 	    if (!c) {
 		result = line;
@@ -828,7 +836,18 @@ edit_read_syntax_rules (WEdit *edit, FIL
 		bg = last_bg;
 	    k->color = this_try_alloc_color_pair (fg, bg);
 	    check_not_a;
-	    num_words++;
+
+	    if (num_words++ > alloc_words_per_context) {
+	    	struct key_word **tmp;
+
+		alloc_words_per_context += 1024;
+
+		if (alloc_words_per_context > max_alloc_words_per_context)
+		    max_alloc_words_per_context = alloc_words_per_context;
+
+		tmp = g_realloc (c->keyword, alloc_words_per_context * sizeof (struct key_word *));
+		c->keyword = tmp;
+	    }
 	} else if (*(args[0]) == '#') {
 	    /* do nothing for comment */
 	} else if (!strcmp (args[0], "file")) {
@@ -870,7 +889,10 @@ edit_read_syntax_rules (WEdit *edit, FIL
     }
 
     {
-	char first_chars[MAX_WORDS_PER_CONTEXT + 2], *p;
+	char *first_chars, *p;
+
+	first_chars = g_malloc (max_alloc_words_per_context + 2);
+
 	for (i = 0; edit->rules[i]; i++) {
 	    c = edit->rules[i];
 	    p = first_chars;
@@ -880,6 +902,8 @@ edit_read_syntax_rules (WEdit *edit, FIL
 	    *p = '\0';
 	    c->keyword_first_chars = g_strdup (first_chars);
 	}
+
+	g_free (first_chars);
     }
 
     return result;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]