From 44a5875b24f033c472af50aa4eec4468c554b7c9 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Mon, 6 Dec 2021 22:43:59 +0000 Subject: vim-patch:8.2.1051: crash when changing a list while using reduce() on it Problem: Crash when changing a list while using reduce() on it. Solution: Lock the list. (closes vim/vim#6330) https://github.com/vim/vim/commit/ca275a05d8b79f6a9101604fdede2373d0dea44e --- src/nvim/eval/funcs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/nvim/eval') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 997096aad4..c80ff8f36a 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7885,7 +7885,7 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr) typval_T initial; typval_T argv[3]; if (argvars[0].v_type == VAR_LIST) { - const list_T *const l = argvars[0].vval.v_list; + list_T *const l = argvars[0].vval.v_list; const listitem_T *li; if (argvars[2].v_type == VAR_UNKNOWN) { @@ -7901,6 +7901,10 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr) li = tv_list_first(l); } + const VarLockStatus prev_locked = tv_list_locked(l); + const int called_emsg_start = called_emsg; + + tv_list_set_lock(l, VAR_FIXED); // disallow the list changing here tv_copy(&initial, rettv); for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) { argv[0] = *rettv; @@ -7908,10 +7912,11 @@ static void f_reduce(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_UNKNOWN; const int r = call_func(func_name, -1, rettv, 2, argv, &funcexe); tv_clear(&argv[0]); - if (r == FAIL) { - return; + if (r == FAIL || called_emsg != called_emsg_start) { + break; } } + tv_list_set_lock(l, prev_locked); } else { const blob_T *const b = argvars[0].vval.v_blob; int i; -- cgit