vim-patch:9.0.1462: recursively calling :defer function if it does :qa

Problem:    Recursively calling :defer function if it does :qa.
Solution:   Clear the defer entry before calling the function. (closes vim/vim#12266)

42994bf678

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq 2023-04-19 07:52:53 +08:00
parent 0a3645a723
commit 8e0ad6e261
2 changed files with 18 additions and 2 deletions

View File

@ -3242,12 +3242,24 @@ static void handle_defer_one(funccall_T *funccal)
{
for (int idx = funccal->fc_defer.ga_len - 1; idx >= 0; idx--) {
defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
if (dr->dr_name == NULL) {
// already being called, can happen if function does ":qa"
continue;
}
funcexe_T funcexe = { .fe_evaluate = true };
typval_T rettv;
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
call_func(dr->dr_name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
char *name = dr->dr_name;
dr->dr_name = NULL;
call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
tv_clear(&rettv);
xfree(dr->dr_name);
xfree(name);
for (int i = dr->dr_argcount - 1; i >= 0; i--) {
tv_clear(&dr->dr_argvars[i]);
}

View File

@ -614,6 +614,7 @@ func Test_defer_quitall()
" vim9script
func DeferLevelTwo()
call writefile(['text'], 'XQuitallTwo', 'D')
call writefile(['quit'], 'XQuitallThree', 'a')
qa!
endfunc
@ -632,6 +633,9 @@ func Test_defer_quitall()
call assert_equal(0, v:shell_error)
call assert_false(filereadable('XQuitallOne'))
call assert_false(filereadable('XQuitallTwo'))
call assert_equal(['quit'], readfile('XQuitallThree'))
call delete('XQuitallThree')
endfunc
func Test_defer_quitall_in_expr_func()