#define CF_WORD 0x01
#define CF_UPPER 0x02
+// Max allowed length for COMPOUND section
+#define COMPOUND_MAX_LEN 100000
+
/*
* Loop through all the siblings of a node (including the node)
*/
char_u *crp;
int cnt;
garray_T *gap;
+ size_t patsize;
+ size_t flagsize;
if (todo < 2)
return SP_FORMERROR; // need at least two bytes
// "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
// Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
// Conversion to utf-8 may double the size.
- c = todo * 2 + 7;
+ if ((size_t)todo > COMPOUND_MAX_LEN)
+ return SP_FORMERROR;
+ patsize = (size_t)todo * 2 + 7;
if (enc_utf8)
- c += todo * 2;
- pat = alloc(c);
+ patsize += (size_t)todo * 2;
+ flagsize = (size_t)todo + 1;
+ pat = alloc(patsize);
if (pat == NULL)
return SP_OTHERERROR;
// We also need a list of all flags that can appear at the start and one
// for all flags.
- cp = alloc(todo + 1);
+ cp = alloc(flagsize);
if (cp == NULL)
{
vim_free(pat);
slang->sl_compstartflags = cp;
*cp = NUL;
- ap = alloc(todo + 1);
+ ap = alloc(flagsize);
if (ap == NULL)
{
vim_free(pat);
// And a list of all patterns in their original form, for checking whether
// compounding may work in match_compoundrule(). This is freed when we
// encounter a wildcard, the check doesn't work then.
- crp = alloc(todo + 1);
+ crp = alloc(flagsize);
slang->sl_comprules = crp;
pp = pat;
" SN_COMPOUND: incorrect comppatlen
call Spellfile_Test(0z080000000007040101000000020165, 'E758:')
+ " SN_COMPOUND: oversized sectionlen
+ let v = eval('0z08004000000803010161' .. repeat('61', 50) .. 'FF')
+ call Spellfile_Test(v, 'E759:')
+
" SN_INFO: missing info
call Spellfile_Test(0z0F0000000005040101, '')