neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 84881674fd702cad5b7572ac868f6d40965a2806
parent 595f7f37a98f3af12fe94ba4332b8f33004b7e4b
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Sat,  5 Nov 2022 17:01:39 +0800

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>

Diffstat:
Mruntime/doc/tagsrch.txt | 2++
Msrc/nvim/tag.c | 11+++++++++++
Msrc/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 @@ -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 @@ -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 @@ -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