diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index d241f39975..20f4140a65 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -699,6 +699,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) break; case SN_MIDWORD: + XFREE_CLEAR(lp->sl_midword); lp->sl_midword = read_string(fd, (size_t)len); // if (lp->sl_midword == NULL) { goto endFAIL; @@ -759,6 +760,7 @@ slang_T *spell_load_file(char *fname, char *lang, slang_T *old_lp, bool silent) break; case SN_SYLLABLE: + XFREE_CLEAR(lp->sl_syllable); lp->sl_syllable = read_string(fd, (size_t)len); // if (lp->sl_syllable == NULL) { goto endFAIL; diff --git a/test/functional/core/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua index 90531de429..1b4a62ecec 100644 --- a/test/functional/core/spellfile_spec.lua +++ b/test/functional/core/spellfile_spec.lua @@ -141,5 +141,34 @@ describe('spellfile', function() n.insert('abc') eq("Vim(normal):E764: Option 'spellfile' is not set", exc_exec('normal! zg')) end) + + it('accepts overwrites on midword and syllable section, errors on memory leak', function() + api.nvim_set_option_value('runtimepath', testdir, {}) + -- stylua: ignore + + -- Set SN_MIDWORD and SN_SYLLABLE twice so the loader overwrites lp->sl_midword. Should + -- not leak memory. + write_file(testdir .. '/spell/en.ascii.spl', + spellheader + -- ┌ Section identifier (#SN_MIDWORD) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + .. '\002\001\000\000\000\003abc' -- SN_MIDWORD (midword = "abc") + .. '\002\001\000\000\000\003def' -- Overwrites SN_MIDWORD (midword = "def") + -- ┌ Section identifier (#SN_SYLLABLE) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + .. '\009\001\000\000\000\003ghi' -- SN_SYLLABLE (syllable = "ghi") + .. '\009\001\000\000\000\003jib' -- Overwrites SN_SYLLABLE (syllable = "jib") + .. '\255' -- End of sections marker + .. '\000\000\000\000' -- LWORDTREE len + .. '\000\000\000\000' -- KWORDTREE len + .. '\000\000\000\000' -- PREFIXTREE len + ) + + api.nvim_set_option_value('spelllang', 'en', {}) + n.command('set spell') -- Should not error + eq(true, api.nvim_get_option_value('spell', {})) + end) end) end)