Skip to content

Commit c36350b

Browse files
committed
patch 8.1.1964: crash when using nested map() and filter()
Problem: Crash when using nested map() and filter(). Solution: Do not set the v:key type to string without clearing the pointer.
1 parent 934470e commit c36350b

3 files changed

Lines changed: 19 additions & 10 deletions

File tree

src/eval.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7185,8 +7185,6 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
71857185
hashtab_T *ht;
71867186
hashitem_T *hi;
71877187
dict_T *d = NULL;
7188-
typval_T save_val;
7189-
typval_T save_key;
71907188
blob_T *b = NULL;
71917189
int rem;
71927190
int todo;
@@ -7225,18 +7223,19 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
72257223
* was not passed as argument. */
72267224
if (expr->v_type != VAR_UNKNOWN)
72277225
{
7226+
typval_T save_val;
7227+
typval_T save_key;
7228+
72287229
prepare_vimvar(VV_VAL, &save_val);
7230+
prepare_vimvar(VV_KEY, &save_key);
72297231

7230-
/* We reset "did_emsg" to be able to detect whether an error
7231-
* occurred during evaluation of the expression. */
7232+
// We reset "did_emsg" to be able to detect whether an error
7233+
// occurred during evaluation of the expression.
72327234
save_did_emsg = did_emsg;
72337235
did_emsg = FALSE;
72347236

7235-
prepare_vimvar(VV_KEY, &save_key);
72367237
if (argvars[0].v_type == VAR_DICT)
72377238
{
7238-
set_vim_var_type(VV_KEY, VAR_STRING);
7239-
72407239
ht = &d->dv_hashtab;
72417240
hash_lock(ht);
72427241
todo = (int)ht->ht_used;
@@ -7274,7 +7273,9 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
72747273
int i;
72757274
typval_T tv;
72767275

7276+
// set_vim_var_nr() doesn't set the type
72777277
set_vim_var_type(VV_KEY, VAR_NUMBER);
7278+
72787279
for (i = 0; i < b->bv_ga.ga_len; i++)
72797280
{
72807281
tv.v_type = VAR_NUMBER;
@@ -7285,7 +7286,7 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
72857286
if (tv.v_type != VAR_NUMBER)
72867287
{
72877288
emsg(_(e_invalblob));
7288-
return;
7289+
break;
72897290
}
72907291
tv.v_type = VAR_NUMBER;
72917292
blob_set(b, i, tv.vval.v_number);
@@ -7300,9 +7301,9 @@ filter_map(typval_T *argvars, typval_T *rettv, int map)
73007301
}
73017302
}
73027303
}
7303-
else
7304+
else // argvars[0].v_type == VAR_LIST
73047305
{
7305-
// argvars[0].v_type == VAR_LIST
7306+
// set_vim_var_nr() doesn't set the type
73067307
set_vim_var_type(VV_KEY, VAR_NUMBER);
73077308

73087309
for (li = l->lv_first; li != NULL; li = nli)

src/testdir/test_filter_map.vim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ func Test_filter_map_list_expr_funcref()
5353
call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], function('s:filter4')))
5454
endfunc
5555

56+
func Test_filter_map_nested()
57+
let x = {"x":10}
58+
let r = map(range(2), 'filter(copy(x), "1")')
59+
call assert_equal([x, x], r)
60+
endfunc
61+
5662
" dict with funcref
5763
func Test_filter_map_dict_expr_funcref()
5864
let dict = {"foo": 1, "bar": 2, "baz": 3}

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1964,
764766
/**/
765767
1963,
766768
/**/

0 commit comments

Comments
 (0)