vim-patch:8.1.1964: crash when using nested map() and filter() (#35715)

Problem:    Crash when using nested map() and filter().
Solution:   Do not set the v:key type to string without clearing the pointer.

c36350bca3

Port filter_map() changes from patch 8.1.1939.

Note: v8.1.1964 reverts a redundant change for `filter_map()` (now
within `filter_map_dict()`) from v8.1.1957.

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Jan Edmund Lazo
2025-09-13 01:31:29 -04:00
committed by GitHub
parent 4c2b7ddcdd
commit f89e1eb036

View File

@@ -5412,8 +5412,6 @@ static void filter_map_dict(dict_T *d, filtermap_T filtermap, const char *func_n
d_ret = rettv->vval.v_dict;
}
vimvars[VV_KEY].vv_type = VAR_STRING;
const VarLockStatus prev_lock = d->dv_lock;
if (d->dv_lock == VAR_UNLOCKED) {
d->dv_lock = VAR_LOCKED;
@@ -5425,11 +5423,11 @@ static void filter_map_dict(dict_T *d, filtermap_T filtermap, const char *func_n
|| var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) {
break;
}
vimvars[VV_KEY].vv_str = xstrdup(di->di_key);
set_vim_var_string(VV_KEY, di->di_key, -1);
typval_T newtv;
bool rem;
int r = filter_map_one(&di->di_tv, expr, filtermap, &newtv, &rem);
tv_clear(&vimvars[VV_KEY].vv_tv);
tv_clear(get_vim_var_tv(VV_KEY));
if (r == FAIL || did_emsg) {
tv_clear(&newtv);
break;
@@ -5496,7 +5494,7 @@ static void filter_map_blob(blob_T *blob_arg, filtermap_T filtermap, typval_T *e
.v_lock = VAR_UNLOCKED,
.vval.v_number = val,
};
vimvars[VV_KEY].vv_nr = idx;
set_vim_var_nr(VV_KEY, idx);
typval_T newtv;
bool rem;
if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL
@@ -5614,7 +5612,7 @@ static void filter_map_list(list_T *l, filtermap_T filtermap, const char *func_n
&& value_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg, TV_TRANSLATE)) {
break;
}
vimvars[VV_KEY].vv_nr = idx;
set_vim_var_nr(VV_KEY, idx);
typval_T newtv;
bool rem;
if (filter_map_one(TV_LIST_ITEM_TV(li), expr, filtermap, &newtv, &rem) == FAIL) {
@@ -5684,15 +5682,16 @@ static void filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap
}
typval_T save_val;
typval_T save_key;
prepare_vimvar(VV_VAL, &save_val);
prepare_vimvar(VV_KEY, &save_key);
// We reset "did_emsg" to be able to detect whether an error
// occurred during evaluation of the expression.
int save_did_emsg = did_emsg;
did_emsg = false;
typval_T save_key;
prepare_vimvar(VV_KEY, &save_key);
if (argvars[0].v_type == VAR_DICT) {
filter_map_dict(argvars[0].vval.v_dict, filtermap, func_name,
arg_errmsg, expr, rettv);