# HG changeset patch # User Bram Moolenaar # Date 1559841306 -7200 # Node ID 8c794a694d669f43d048a0dc30f991b0e0a214ac # Parent 8a2324f4a8baec9614bc4a3da48c137ebad97979 patch 8.1.1485: double free when garbage_collect() is used in autocommand commit https://github.com/vim/vim/commit/c07f67ad0e9c48a07d49f2d67eb63e183a22386a Author: Bram Moolenaar Date: Thu Jun 6 19:03:17 2019 +0200 patch 8.1.1485: double free when garbage_collect() is used in autocommand Problem: Double free when garbage_collect() is used in autocommand. Solution: Have garbage collection also set the copyID in funccal_stack. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -430,12 +430,11 @@ eval_clear(void) vim_free(SCRIPT_SV(i)); ga_clear(&ga_scripts); - // functions need to be freed before gargabe collecting, otherwise local - // variables might be freed twice. - free_all_functions(); - // unreferenced lists and dicts (void)garbage_collect(FALSE); + + // functions not garbage collected + free_all_functions(); } #endif diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -4030,11 +4030,18 @@ set_ref_in_funccal(funccall_T *fc, int c int set_ref_in_call_stack(int copyID) { - int abort = FALSE; - funccall_T *fc; + int abort = FALSE; + funccall_T *fc; + funccal_entry_T *entry; for (fc = current_funccal; fc != NULL; fc = fc->caller) abort = abort || set_ref_in_funccal(fc, copyID); + + // Also go through the funccal_stack. + for (entry = funccal_stack; entry != NULL; entry = entry->next) + for (fc = entry->top_funccal; fc != NULL; fc = fc->caller) + abort = abort || set_ref_in_funccal(fc, copyID); + return abort; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1485, +/**/ 1484, /**/ 1483,