0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

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 #4554, closes #4547)
This commit is contained in:
Bram Moolenaar
2019-06-17 21:18:41 +02:00
parent ad24a71e22
commit 6e5000d493
3 changed files with 26 additions and 15 deletions

View File

@@ -1665,6 +1665,17 @@ func Test_refcount()
delfunc DictFunc delfunc DictFunc
endfunc 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
"------------------------------------------------------------------------------- "-------------------------------------------------------------------------------
" Modelines {{{1 " Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker " vim: ts=8 sw=4 tw=80 fdm=marker

View File

@@ -935,12 +935,9 @@ call_user_func(
v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX; v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
} }
if (isdefault) // Note: the values are copied directly to avoid alloc/free.
v->di_tv = def_rettv; // "argvars" must have VAR_FIXED for v_lock.
else v->di_tv = isdefault ? def_rettv : argvars[i];
// Note: the values are copied directly to avoid alloc/free.
// "argvars" must have VAR_FIXED for v_lock.
v->di_tv = argvars[i];
v->di_tv.v_lock = VAR_FIXED; v->di_tv.v_lock = VAR_FIXED;
if (addlocal) if (addlocal)
@@ -1540,7 +1537,6 @@ call_func(
} }
} }
/* /*
* Execute the function if executing and no errors were detected. * Execute the function if executing and no errors were detected.
*/ */
@@ -3998,13 +3994,13 @@ set_ref_in_previous_funccal(int copyID)
int abort = FALSE; int abort = FALSE;
funccall_T *fc; funccall_T *fc;
for (fc = previous_funccal; fc != NULL; fc = fc->caller) for (fc = previous_funccal; !abort && fc != NULL; fc = fc->caller)
{ {
fc->fc_copyID = copyID + 1; fc->fc_copyID = copyID + 1;
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, abort = abort
NULL); || 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, || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
NULL); || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL);
} }
return abort; return abort;
} }
@@ -4017,9 +4013,11 @@ set_ref_in_funccal(funccall_T *fc, int copyID)
if (fc->fc_copyID != copyID) if (fc->fc_copyID != copyID)
{ {
fc->fc_copyID = copyID; fc->fc_copyID = copyID;
abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); abort = abort
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
abort = abort || set_ref_in_func(NULL, fc->func, copyID); || 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; return abort;
} }

View File

@@ -777,6 +777,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1563,
/**/ /**/
1562, 1562,
/**/ /**/