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)
ca275a05d8
This commit is contained in:
Sean Dewar
2021-12-06 22:43:59 +00:00
committed by zeertzjq
parent af0bae38e2
commit 44a5875b24
2 changed files with 17 additions and 3 deletions

View File

@@ -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;