diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 69e7ae446c..8e6342de41 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2938,7 +2938,8 @@ static void spell_soundfold_wsal(slang_T *slang, const char *inword, char *res) // Check all rules for the same index byte. // If c is 0x300 need extra check for the end of the array, as // (c & 0xff) is NUL. - for (; ((ws = smp[n].sm_lead_w)[0] & 0xff) == (c & 0xff) + for (; n < slang->sl_sal.ga_len + && ((ws = smp[n].sm_lead_w)[0] & 0xff) == (c & 0xff) && ws[0] != NUL; n++) { // Quickly skip entries that don't match the word. Most // entries are less than three chars, optimize for that. diff --git a/test/old/testdir/test_spell_utf8.vim b/test/old/testdir/test_spell_utf8.vim index f4ad23fa7b..a036ea97c6 100644 --- a/test/old/testdir/test_spell_utf8.vim +++ b/test/old/testdir/test_spell_utf8.vim @@ -828,5 +828,18 @@ func Test_spell_suggest_too_long() bwipe! endfunc +" A SAL rule that is too long to case-fold must not move the sentinel entry +" out of its last position in the sl_sal array. +func Test_spellfile_long_sal_rule() + call writefile(['1', 'ab'], 'Xlongsal.dic', 'D') + call writefile(['SAL ' .. repeat('w', 299) .. ' a', + \ "SAL a\u00e9 a"], 'Xlongsal.aff', 'D') + mkspell! Xlongsal Xlongsal + set spelllang=Xlongsal.utf-8.spl spell + " must not crash + call soundfold('ab') + set spelllang& spell& + call delete('Xlongsal.utf-8.spl') +endfunc " vim: shiftwidth=2 sts=2 expandtab