2004-01-31 Jakub Jelinek * syntax.c (edit_read_syntax_rules): Fix boundary conditions. 2003-06-13 David Sterba * 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. --- mc/edit/syntax.c.jj 2002-12-15 19:55:53.000000000 +0100 +++ mc/edit/syntax.c 2004-01-30 21:13:51.000000000 +0100 @@ -588,13 +588,16 @@ static int edit_read_syntax_rules (WEdit 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_malloc (alloc_contexts * sizeof (struct context_rule *)); for (;;) { char **a; @@ -659,6 +662,8 @@ static int edit_read_syntax_rules (WEdit c->right = g_strdup (" "); num_contexts = 0; } else { + /* Terminate previous context. */ + r[num_contexts - 1]->keyword[num_words] = NULL; c = r[num_contexts] = g_malloc0 (sizeof (struct context_rule)); if (!strcmp (*a, "exclusive")) { a++; @@ -693,10 +698,7 @@ static int edit_read_syntax_rules (WEdit 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_malloc (alloc_words_per_context * sizeof (struct key_word *)); num_words = 1; c->keyword[0] = g_malloc0 (sizeof (struct key_word)); fg = *a; @@ -710,7 +712,15 @@ static int edit_read_syntax_rules (WEdit 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; @@ -757,7 +767,18 @@ static int edit_read_syntax_rules (WEdit 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")) { @@ -771,6 +792,12 @@ static int edit_read_syntax_rules (WEdit free_args (args); syntax_g_free (l); + /* Terminate context array. */ + if (num_contexts > 0) { + r[num_contexts - 1]->keyword[num_words] = NULL; + r[num_contexts] = NULL; + } + if (!edit->rules[0]) syntax_g_free (edit->rules); @@ -783,7 +810,10 @@ static int edit_read_syntax_rules (WEdit } { - 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; @@ -794,6 +824,8 @@ static int edit_read_syntax_rules (WEdit c->keyword_first_chars = g_malloc0 (strlen (first_chars) + 2); strcpy (c->keyword_first_chars, first_chars); } + + g_free (first_chars); } return result;