diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 466aaf4578..f934b9f94e 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1553,7 +1553,9 @@ static int set_sofo(slang_T *lp, const char *from, const char *to) lp->sl_sofo = true; // First count the number of items for each list. Temporarily use - // sl_sal_first[] for this. + // sl_sal_first[] for this. Reset it first: a preceding SN_SAL section + // may have set the entries to -1 via set_sal_first(). + memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); for (p = from, s = to; *p != NUL && *s != NUL;) { const int c = mb_cptr2char_adv(&p); s += utf_ptr2len(s); diff --git a/test/old/testdir/test_spellfile.vim b/test/old/testdir/test_spellfile.vim index 0938e4cfd1..9919821a6f 100644 --- a/test/old/testdir/test_spellfile.vim +++ b/test/old/testdir/test_spellfile.vim @@ -322,6 +322,11 @@ func Test_spellfile_format_error() " SN_SOFO: multi-byte characters in sofofrom and sofoto call Spellfile_Test(0z0600000000080002CF810002CF82FF000000000000000000000000, '') + " SN_SAL (empty) followed by SN_SOFO with two multi-byte 'from' characters + " sharing the same low byte. A preceding SN_SAL poisons sl_sal_first[], so + " without a reset set_sofo() under-counts and writes out of bounds. + call Spellfile_Test(0z05000000000300000006000000000A0004CAABCEAB00024142FF000000000000000000000000, '') + " SN_COMPOUND: compmax is less than 2 call Spellfile_Test(0z08000000000101, 'E759:')