mirror of
https://github.com/neovim/neovim.git
synced 2024-12-25 13:45:15 -07:00
fix: segfault in find_tagfunc_tags #18841
fixes #15221 I tried to reproduce with a test, but failed. The below patch is able to cause the out of bound access (I verified by adding a check to the code), but it doesn't seg fault or trigger asan/valgrind errors. ``` diff --git a/src/nvim/testdir/test_tagfunc.vim b/src/nvim/testdir/test_tagfunc.vim index ffc1d63b9..22828a39f 100644 --- a/src/nvim/testdir/test_tagfunc.vim +++ b/src/nvim/testdir/test_tagfunc.vim @@ -117,4 +117,26 @@ func Test_tagfunc_settagstack() delfunc Mytagfunc2 endfunc +func Test_tagfunc_settagstack_many() + + func Mytagfunc1(pat, flags, info) + return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] + endfunc + set tagfunc=Mytagfunc1 + call writefile([''], 'Xtest') + + for i in range(0,20) + let pos = [bufnr()] + getcurpos()[1:] + let newtag = [{'tagname' : 'mytag' + i, 'from' : pos}] + call settagstack(1, {'items' : newtag}, 'a') + call settagstack(1, {'curidx' : 21}) + endfor + + tag + + call delete('Xtest') + set tagfunc& + delfunc Mytagfunc1 +endfunc ```
This commit is contained in:
parent
11e0fea8ba
commit
bf327368d8
@ -1143,7 +1143,15 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
|
||||
typval_T args[4];
|
||||
typval_T rettv;
|
||||
char_u flagString[4];
|
||||
taggy_T *tag = &curwin->w_tagstack[curwin->w_tagstackidx];
|
||||
taggy_T *tag = NULL;
|
||||
|
||||
if (curwin->w_tagstacklen > 0) {
|
||||
if (curwin->w_tagstackidx == curwin->w_tagstacklen) {
|
||||
tag = &curwin->w_tagstack[curwin->w_tagstackidx - 1];
|
||||
} else {
|
||||
tag = &curwin->w_tagstack[curwin->w_tagstackidx];
|
||||
}
|
||||
}
|
||||
|
||||
if (*curbuf->b_p_tfu == NUL) {
|
||||
return FAIL;
|
||||
@ -1156,7 +1164,7 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
|
||||
|
||||
// create 'info' dict argument
|
||||
dict_T *const d = tv_dict_alloc_lock(VAR_FIXED);
|
||||
if (tag->user_data != NULL) {
|
||||
if (tag != NULL && tag->user_data != NULL) {
|
||||
tv_dict_add_str(d, S_LEN("user_data"), (const char *)tag->user_data);
|
||||
}
|
||||
if (buf_ffname != NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user