diff --git a/src/spellfile.c b/src/spellfile.c index f0d6d96a47f02..4a0de5237ffea 100644 --- a/src/spellfile.c +++ b/src/spellfile.c @@ -4366,6 +4366,23 @@ wordtree_alloc(spellinfo_T *spin) return (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE); } +/* + * Return TRUE if "word" contains valid word characters. + * Control characters and trailing '/' are invalid. Space is OK. + */ + static int +valid_spell_word(char_u *word) +{ + char_u *p; + + if (enc_utf8 && !utf_valid_string(word, NULL)) + return FALSE; + for (p = word; *p != NUL; p += mb_ptr2len(p)) + if (*p < ' ' || (p[0] == '/' && p[1] == NUL)) + return FALSE; + return TRUE; +} + /* * Store a word in the tree(s). * Always store it in the case-folded tree. For a keep-case word this is @@ -4391,7 +4408,7 @@ store_word( char_u *p; // Avoid adding illegal bytes to the word tree. - if (enc_utf8 && !utf_valid_string(word, NULL)) + if (!valid_spell_word(word)) return FAIL; (void)spell_casefold(curwin, word, len, foldword, MAXWLEN); @@ -6194,7 +6211,7 @@ spell_add_word( int i; char_u *spf; - if (enc_utf8 && !utf_valid_string(word, NULL)) + if (!valid_spell_word(word)) { emsg(_(e_illegal_character_in_word)); return; diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim index 0fd5ed91780fb..0187a175a8264 100644 --- a/src/testdir/test_spell.vim +++ b/src/testdir/test_spell.vim @@ -854,6 +854,21 @@ func Test_spellsuggest_too_deep() bwipe! endfunc +func Test_spell_good_word_invalid() + " This was adding a word with a 0x02 byte, which causes havoc. + enew + norm o0 + sil! norm rzzWs00/ + 2 + sil! norm VzGprzzW + sil! norm z= + + bwipe! + " clear the internal word list + set enc=latin1 + set enc=utf-8 +endfunc + func LoadAffAndDic(aff_contents, dic_contents) set enc=latin1 set spellfile= diff --git a/src/version.c b/src/version.c index 26cb768a82541..23798ee560bde 100644 --- a/src/version.c +++ b/src/version.c @@ -735,6 +735,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 21, /**/ 20, /**/