Merge pull request #17135 from seandewar/vim-8.2.0175

vim-patch:8.2.0175: crash when removing list element in map()
This commit is contained in:
bfredl 2022-01-27 08:47:01 +01:00 committed by GitHub
commit 618f7079e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 0 deletions

View File

@ -6468,6 +6468,10 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
if (argvars[0].v_type == VAR_DICT) {
vimvars[VV_KEY].vv_type = VAR_STRING;
const VarLockStatus prev_lock = d->dv_lock;
if (map && d->dv_lock == VAR_UNLOCKED) {
d->dv_lock = VAR_LOCKED;
}
ht = &d->dv_hashtab;
hash_lock(ht);
todo = (int)ht->ht_used;
@ -6498,6 +6502,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
}
}
hash_unlock(ht);
d->dv_lock = prev_lock;
} else if (argvars[0].v_type == VAR_BLOB) {
vimvars[VV_KEY].vv_type = VAR_NUMBER;
@ -6530,6 +6535,10 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
assert(argvars[0].v_type == VAR_LIST);
vimvars[VV_KEY].vv_type = VAR_NUMBER;
const VarLockStatus prev_lock = tv_list_locked(l);
if (map && tv_list_locked(l) == VAR_UNLOCKED) {
tv_list_set_lock(l, VAR_LOCKED);
}
for (listitem_T *li = tv_list_first(l); li != NULL;) {
if (map
&& var_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg,
@ -6548,6 +6557,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
}
idx++;
}
tv_list_set_lock(l, prev_lock);
}
restore_vimvar(VV_KEY, &save_key);

View File

@ -88,4 +88,14 @@ func Test_map_filter_fails()
call assert_fails("let l = filter('abc', '\"> \" . v:val')", 'E896:')
endfunc
func Test_map_and_modify()
let l = ["abc"]
" cannot change the list halfway a map()
call assert_fails('call map(l, "remove(l, 0)[0]")', 'E741:')
let d = #{a: 1, b: 2, c: 3}
call assert_fails('call map(d, "remove(d, v:key)[0]")', 'E741:')
call assert_fails('echo map(d, {k,v -> remove(d, k)})', 'E741:')
endfunc
" vim: shiftwidth=2 sts=2 expandtab