diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-05 17:01:39 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-11-07 08:24:48 +0800 |
commit | 84881674fd702cad5b7572ac868f6d40965a2806 (patch) | |
tree | 67e6e2d09e8e33ed6f5beb93299674288b943841 | |
parent | 595f7f37a98f3af12fe94ba4332b8f33004b7e4b (diff) | |
download | rneovim-84881674fd702cad5b7572ac868f6d40965a2806.tar.gz rneovim-84881674fd702cad5b7572ac868f6d40965a2806.tar.bz2 rneovim-84881674fd702cad5b7572ac868f6d40965a2806.zip |
vim-patch:9.0.0389: crash when 'tagfunc' closes the window
Problem: Crash when 'tagfunc' closes the window.
Solution: Bail out when the window was closed.
https://github.com/vim/vim/commit/ccfde4d028e891a41e3548323c3d47b06fb0b83e
Add docs for E1299 from Vim runtime.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r-- | runtime/doc/tagsrch.txt | 2 | ||||
-rw-r--r-- | src/nvim/tag.c | 11 | ||||
-rw-r--r-- | src/nvim/testdir/test_tagfunc.vim | 13 |
3 files changed, 26 insertions, 0 deletions
diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt index d079db0717..aab6f78315 100644 --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -909,6 +909,8 @@ If the function returns |v:null| instead of a List, a standard tag lookup will be performed instead. It is not allowed to change the tagstack from inside 'tagfunc'. *E986* +It is not allowed to close a window or change window from inside 'tagfunc'. +*E1299* The following is a hypothetical example of a function used for 'tagfunc'. It uses the output of |taglist()| to generate the result: a list of tags in the diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 5216919d98..16d6629c2e 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -106,6 +106,8 @@ static char_u *recurmsg = (char_u *)N_("E986: cannot modify the tag stack within tagfunc"); static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc"); +static char e_window_unexpectedly_close_while_searching_for_tags[] + = N_("E1299: Window unexpectedly closed while searching for tags"); static char *tagmatchname = NULL; // name of last used tag @@ -501,6 +503,15 @@ void do_tag(char *tag, int type, int count, int forceit, int verbose) // found: all matches found. } + // A tag function may do anything, which may cause various + // information to become invalid. At least check for the tagstack + // to still be the same. + if (tagstack != curwin->w_tagstack) { + emsg(_(e_window_unexpectedly_close_while_searching_for_tags)); + FreeWild(new_num_matches, new_matches); + break; + } + // If there already were some matches for the same name, move them // to the start. Avoids that the order changes when using // ":tnext" and jumping to another file. diff --git a/src/nvim/testdir/test_tagfunc.vim b/src/nvim/testdir/test_tagfunc.vim index ad761f1b23..8690e30e77 100644 --- a/src/nvim/testdir/test_tagfunc.vim +++ b/src/nvim/testdir/test_tagfunc.vim @@ -285,4 +285,17 @@ func Test_tagfunc_wipes_buffer() set tagfunc= endfunc +func Test_tagfunc_closes_window() + split any + func MytagfuncClose(pat, flags, info) + close + return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] + endfunc + set tagfunc=MytagfuncClose + call assert_fails('tag xyz', 'E1299:') + + set tagfunc= +endfunc + + " vim: shiftwidth=2 sts=2 expandtab |