forked from aniani/vim
patch 8.2.3756: might crash when callback is not valid
Problem: might crash when callback is not valid. Solution: Check for valid callback. (Yegappan Lakshmanan, closes #9293)
This commit is contained in:
parent
92c33eb273
commit
4dc24eb5ad
@ -2329,14 +2329,12 @@ set_thesaurusfunc_option(void)
|
||||
if (*curbuf->b_p_tsrfu != NUL)
|
||||
{
|
||||
// buffer-local option set
|
||||
free_callback(&curbuf->b_tsrfu_cb);
|
||||
retval = option_set_callback_func(curbuf->b_p_tsrfu,
|
||||
&curbuf->b_tsrfu_cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// global option set
|
||||
free_callback(&tsrfu_cb);
|
||||
retval = option_set_callback_func(p_tsrfu, &tsrfu_cb);
|
||||
}
|
||||
|
||||
|
@ -1578,6 +1578,7 @@ invoke_prompt_interrupt(void)
|
||||
{
|
||||
typval_T rettv;
|
||||
typval_T argv[1];
|
||||
int ret;
|
||||
|
||||
if (curbuf->b_prompt_interrupt.cb_name == NULL
|
||||
|| *curbuf->b_prompt_interrupt.cb_name == NUL)
|
||||
@ -1585,9 +1586,9 @@ invoke_prompt_interrupt(void)
|
||||
argv[0].v_type = VAR_UNKNOWN;
|
||||
|
||||
got_int = FALSE; // don't skip executing commands
|
||||
call_callback(&curbuf->b_prompt_interrupt, -1, &rettv, 0, argv);
|
||||
ret = call_callback(&curbuf->b_prompt_interrupt, -1, &rettv, 0, argv);
|
||||
clear_tv(&rettv);
|
||||
return TRUE;
|
||||
return ret == FAIL ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7210,7 +7210,7 @@ option_set_callback_func(char_u *optval UNUSED, callback_T *optcb UNUSED)
|
||||
return FAIL;
|
||||
|
||||
cb = get_callback(tv);
|
||||
if (cb.cb_name == NULL)
|
||||
if (cb.cb_name == NULL || *cb.cb_name == NUL)
|
||||
{
|
||||
free_tv(tv);
|
||||
return FAIL;
|
||||
|
@ -1361,7 +1361,8 @@ find_tagfunc_tags(
|
||||
dict_T *d;
|
||||
taggy_T *tag = &curwin->w_tagstack[curwin->w_tagstackidx];
|
||||
|
||||
if (*curbuf->b_p_tfu == NUL)
|
||||
if (*curbuf->b_p_tfu == NUL || curbuf->b_tfu_cb.cb_name == NULL
|
||||
|| *curbuf->b_tfu_cb.cb_name == NUL)
|
||||
return FAIL;
|
||||
|
||||
args[0].v_type = VAR_STRING;
|
||||
|
@ -257,6 +257,19 @@ func Test_imactivatefunc_imstatusfunc_callback()
|
||||
set imstatusfunc=()\ =>\ IMstatusfunc1(a)
|
||||
call assert_fails('normal! i', 'E117:')
|
||||
|
||||
" set 'imactivatefunc' and 'imstatusfunc' to a non-existing function
|
||||
set imactivatefunc=IMactivatefunc1
|
||||
set imstatusfunc=IMstatusfunc1
|
||||
call assert_fails("set imactivatefunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("set imstatusfunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &imactivatefunc = function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &imstatusfunc = function('NonExistingFunc')", 'E700:')
|
||||
let g:IMactivatefunc_called = 0
|
||||
let g:IMstatusfunc_called = 0
|
||||
normal! i
|
||||
call assert_equal(2, g:IMactivatefunc_called)
|
||||
call assert_equal(2, g:IMstatusfunc_called)
|
||||
|
||||
" cleanup
|
||||
delfunc IMactivatefunc1
|
||||
delfunc IMstatusfunc1
|
||||
|
@ -1074,6 +1074,15 @@ func Test_completefunc_callback()
|
||||
call assert_fails('call feedkeys("A\<C-X>\<C-U>\<Esc>", "x")', 'E117:')
|
||||
call assert_equal([], g:MycompleteFunc2_args)
|
||||
|
||||
" set 'completefunc' to a non-existing function
|
||||
set completefunc=MycompleteFunc2
|
||||
call setline(1, 'five')
|
||||
call assert_fails("set completefunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &completefunc = function('NonExistingFunc')", 'E700:')
|
||||
let g:MycompleteFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'five']], g:MycompleteFunc2_args)
|
||||
|
||||
" cleanup
|
||||
delfunc MycompleteFunc1
|
||||
delfunc MycompleteFunc2
|
||||
@ -1285,6 +1294,15 @@ func Test_omnifunc_callback()
|
||||
call assert_fails('call feedkeys("A\<C-X>\<C-O>\<Esc>", "x")', 'E117:')
|
||||
call assert_equal([], g:MyomniFunc2_args)
|
||||
|
||||
" set 'omnifunc' to a non-existing function
|
||||
set omnifunc=MyomniFunc2
|
||||
call setline(1, 'nine')
|
||||
call assert_fails("set omnifunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &omnifunc = function('NonExistingFunc')", 'E700:')
|
||||
let g:MyomniFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'nine']], g:MyomniFunc2_args)
|
||||
|
||||
" cleanup
|
||||
delfunc MyomniFunc1
|
||||
delfunc MyomniFunc2
|
||||
@ -1522,6 +1540,16 @@ func Test_thesaurusfunc_callback()
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")
|
||||
call assert_equal('sunday', getline(1))
|
||||
call assert_equal([[1, ''], [0, 'sun']], g:MytsrFunc4_args)
|
||||
%bw!
|
||||
|
||||
" set 'thesaurusfunc' to a non-existing function
|
||||
set thesaurusfunc=MytsrFunc2
|
||||
call setline(1, 'ten')
|
||||
call assert_fails("set thesaurusfunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &thesaurusfunc = function('NonExistingFunc')", 'E700:')
|
||||
let g:MytsrFunc2_args = []
|
||||
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
|
||||
call assert_equal([[1, ''], [0, 'ten']], g:MytsrFunc2_args)
|
||||
|
||||
" cleanup
|
||||
set thesaurusfunc&
|
||||
|
@ -317,6 +317,11 @@ func Test_tagfunc_callback()
|
||||
call assert_fails("tag a17", "E117:")
|
||||
call assert_equal([], g:MytagFunc3_args)
|
||||
|
||||
" set 'tagfunc' to a non-existing function
|
||||
call assert_fails("set tagfunc=function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("let &tagfunc = function('NonExistingFunc')", 'E700:')
|
||||
call assert_fails("tag axb123", 'E426:')
|
||||
|
||||
" cleanup
|
||||
delfunc MytagFunc1
|
||||
delfunc MytagFunc2
|
||||
|
@ -3146,6 +3146,7 @@ get_callback_depth(void)
|
||||
|
||||
/*
|
||||
* Invoke call_func() with a callback.
|
||||
* Returns FAIL if the callback could not be called.
|
||||
*/
|
||||
int
|
||||
call_callback(
|
||||
@ -3159,6 +3160,8 @@ call_callback(
|
||||
funcexe_T funcexe;
|
||||
int ret;
|
||||
|
||||
if (callback->cb_name == NULL || *callback->cb_name == NUL)
|
||||
return FAIL;
|
||||
CLEAR_FIELD(funcexe);
|
||||
funcexe.evaluate = TRUE;
|
||||
funcexe.partial = callback->cb_partial;
|
||||
@ -3170,7 +3173,7 @@ call_callback(
|
||||
|
||||
/*
|
||||
* call the 'callback' function and return the result as a number.
|
||||
* Returns -1 when calling the function fails. Uses argv[0] to argv[argc - 1]
|
||||
* Returns -2 when calling the function fails. Uses argv[0] to argv[argc - 1]
|
||||
* for the function arguments. argv[argc] should have type VAR_UNKNOWN.
|
||||
*/
|
||||
varnumber_T
|
||||
@ -3184,7 +3187,7 @@ call_callback_retnr(
|
||||
varnumber_T retval;
|
||||
|
||||
if (call_callback(callback, 0, &rettv, argcount, argvars) == FAIL)
|
||||
return -1;
|
||||
return -2;
|
||||
|
||||
retval = tv_get_number_chk(&rettv, NULL);
|
||||
clear_tv(&rettv);
|
||||
|
@ -753,6 +753,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3756,
|
||||
/**/
|
||||
3755,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user