vim-patch:8.1.1563: crash when using closures

Problem:    Crash when using closures.
Solution:   Set reference in varlist of funccal when running the garbage
            collector. (Ozaki Kiichi, closes vim/vim#4554, closes vim/vim#4547)
6e5000d493
This commit is contained in:
erw7
2019-09-08 11:04:37 +09:00
committed by Jan Edmund Lazo
parent 3430e40c60
commit 7cb38d5ac4
2 changed files with 23 additions and 6 deletions

View File

@@ -3347,9 +3347,13 @@ bool set_ref_in_previous_funccal(int copyID)
{
bool abort = false;
for (funccall_T *fc = previous_funccal; fc != NULL; fc = fc->caller) {
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL);
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL);
for (funccall_T *fc = previous_funccal; !abort && fc != NULL;
fc = fc->caller) {
fc->fc_copyID = copyID + 1;
abort = abort
|| set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_list(&fc->l_varlist, copyID + 1, NULL);
}
return abort;
}
@@ -3360,9 +3364,11 @@ static bool set_ref_in_funccal(funccall_T *fc, int copyID)
if (fc->fc_copyID != copyID) {
fc->fc_copyID = copyID;
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
abort = abort || set_ref_in_func(NULL, fc->func, copyID);
abort = abort
|| set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
|| set_ref_in_list(&fc->l_varlist, copyID, NULL)
|| set_ref_in_func(NULL, fc->func, copyID);
}
return abort;
}

View File

@@ -1409,6 +1409,17 @@ func Test_compound_assignment_operators()
let @/ = ''
endfunc
func! Test_funccall_garbage_collect()
func Func(x, ...)
call add(a:x, a:000)
endfunc
call Func([], [])
" Must not crash cause by invalid freeing
call test_garbagecollect_now()
call assert_true(v:true)
delfunc Func
endfunc
func Test_function_defined_line()
if has('gui_running')
" Can't catch the output of gvim.