1
0
forked from aniani/vim

updated for version 7.3.109

Problem:    Processing new Esperanto spell file fails and crashes Vim.
            (Dominique Pelle)
Solution:   When running out of memory give an error.  Handle '?' in
            COMPOUNDRULE properly.
This commit is contained in:
Bram Moolenaar 2011-02-01 13:59:48 +01:00
parent 3c2d6534ef
commit c98d5ee923
2 changed files with 43 additions and 20 deletions

View File

@ -3634,7 +3634,7 @@ read_compound(fd, slang, len)
} }
/* Add all flags to "sl_compallflags". */ /* Add all flags to "sl_compallflags". */
if (vim_strchr((char_u *)"+*[]/", c) == NULL if (vim_strchr((char_u *)"?*+[]/", c) == NULL
&& !byte_in_str(slang->sl_compallflags, c)) && !byte_in_str(slang->sl_compallflags, c))
{ {
*ap++ = c; *ap++ = c;
@ -3664,7 +3664,7 @@ read_compound(fd, slang, len)
/* Copy flag to "sl_comprules", unless we run into a wildcard. */ /* Copy flag to "sl_comprules", unless we run into a wildcard. */
if (crp != NULL) if (crp != NULL)
{ {
if (c == '+' || c == '*') if (c == '?' || c == '+' || c == '*')
{ {
vim_free(slang->sl_comprules); vim_free(slang->sl_comprules);
slang->sl_comprules = NULL; slang->sl_comprules = NULL;
@ -3682,8 +3682,8 @@ read_compound(fd, slang, len)
} }
else /* normal char, "[abc]" and '*' are copied as-is */ else /* normal char, "[abc]" and '*' are copied as-is */
{ {
if (c == '+' || c == '~') if (c == '?' || c == '+' || c == '~')
*pp++ = '\\'; /* "a+" becomes "a\+" */ *pp++ = '\\'; /* "a?" becomes "a\?", "a+" becomes "a\+" */
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
if (enc_utf8) if (enc_utf8)
pp += mb_char2bytes(c, pp); pp += mb_char2bytes(c, pp);
@ -4951,6 +4951,8 @@ typedef struct spellinfo_S
sblock_T *si_blocks; /* memory blocks used */ sblock_T *si_blocks; /* memory blocks used */
long si_blocks_cnt; /* memory blocks allocated */ long si_blocks_cnt; /* memory blocks allocated */
int si_did_emsg; /* TRUE when ran out of memory */
long si_compress_cnt; /* words to add before lowering long si_compress_cnt; /* words to add before lowering
compression limit */ compression limit */
wordnode_T *si_first_free; /* List of nodes that have been freed during wordnode_T *si_first_free; /* List of nodes that have been freed during
@ -5477,21 +5479,25 @@ spell_read_aff(spin, fname)
} }
else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2))
{ {
/* Concatenate this string to previously defined ones, using a /* Don't use the first rule if it is a number. */
* slash to separate them. */ if (compflags != NULL || *skipdigits(items[1]) != NUL)
l = (int)STRLEN(items[1]) + 1;
if (compflags != NULL)
l += (int)STRLEN(compflags) + 1;
p = getroom(spin, l, FALSE);
if (p != NULL)
{ {
/* Concatenate this string to previously defined ones,
* using a slash to separate them. */
l = (int)STRLEN(items[1]) + 1;
if (compflags != NULL) if (compflags != NULL)
l += (int)STRLEN(compflags) + 1;
p = getroom(spin, l, FALSE);
if (p != NULL)
{ {
STRCPY(p, compflags); if (compflags != NULL)
STRCAT(p, "/"); {
STRCPY(p, compflags);
STRCAT(p, "/");
}
STRCAT(p, items[1]);
compflags = p;
} }
STRCAT(p, items[1]);
compflags = p;
} }
} }
else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2) else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
@ -6291,7 +6297,7 @@ process_compflags(spin, aff, compflags)
for (p = compflags; *p != NUL; ) for (p = compflags; *p != NUL; )
{ {
if (vim_strchr((char_u *)"/*+[]", *p) != NULL) if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
/* Copy non-flag characters directly. */ /* Copy non-flag characters directly. */
*tp++ = *p++; *tp++ = *p++;
else else
@ -6320,7 +6326,7 @@ process_compflags(spin, aff, compflags)
{ {
check_renumber(spin); check_renumber(spin);
id = spin->si_newcompID--; id = spin->si_newcompID--;
} while (vim_strchr((char_u *)"/+*[]\\-^", id) != NULL); } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL);
ci->ci_newID = id; ci->ci_newID = id;
hash_add(&aff->af_comp, ci->ci_key); hash_add(&aff->af_comp, ci->ci_key);
} }
@ -7364,10 +7370,21 @@ getroom(spin, len, align)
if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) if (bl == NULL || bl->sb_used + len > SBLOCKSIZE)
{ {
/* Allocate a block of memory. This is not freed until much later. */ if (len >= SBLOCKSIZE)
bl = (sblock_T *)alloc_clear((unsigned)(sizeof(sblock_T) + SBLOCKSIZE)); bl = NULL;
else
/* Allocate a block of memory. It is not freed until much later. */
bl = (sblock_T *)alloc_clear(
(unsigned)(sizeof(sblock_T) + SBLOCKSIZE));
if (bl == NULL) if (bl == NULL)
{
if (!spin->si_did_emsg)
{
EMSG(_("E845: Insufficient memory, word list will be incomplete"));
spin->si_did_emsg = TRUE;
}
return NULL; return NULL;
}
bl->sb_next = spin->si_blocks; bl->sb_next = spin->si_blocks;
spin->si_blocks = bl; spin->si_blocks = bl;
bl->sb_used = 0; bl->sb_used = 0;
@ -7382,6 +7399,7 @@ getroom(spin, len, align)
/* /*
* Make a copy of a string into memory allocated with getroom(). * Make a copy of a string into memory allocated with getroom().
* Returns NULL when out of memory.
*/ */
static char_u * static char_u *
getroom_save(spin, s) getroom_save(spin, s)
@ -7416,6 +7434,7 @@ free_blocks(bl)
/* /*
* Allocate the root of a word tree. * Allocate the root of a word tree.
* Returns NULL when out of memory.
*/ */
static wordnode_T * static wordnode_T *
wordtree_alloc(spin) wordtree_alloc(spin)
@ -7700,6 +7719,7 @@ spell_check_msm()
/* /*
* Get a wordnode_T, either from the list of previously freed nodes or * Get a wordnode_T, either from the list of previously freed nodes or
* allocate a new one. * allocate a new one.
* Returns NULL when out of memory.
*/ */
static wordnode_T * static wordnode_T *
get_wordnode(spin) get_wordnode(spin)
@ -7717,7 +7737,8 @@ get_wordnode(spin)
--spin->si_free_count; --spin->si_free_count;
} }
#ifdef SPELL_PRINTTREE #ifdef SPELL_PRINTTREE
n->wn_nr = ++spin->si_wordnode_nr; if (n != NULL)
n->wn_nr = ++spin->si_wordnode_nr;
#endif #endif
return n; return n;
} }

View File

@ -714,6 +714,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
109,
/**/ /**/
108, 108,
/**/ /**/