@@ -1985,10 +1985,18 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
19851985 : N_ ("filter() argument" ));
19861986 int save_did_emsg ;
19871987 int idx = 0 ;
1988+ type_T * type = NULL ;
1989+ garray_T type_list ;
19881990
19891991 // map() and filter() return the first argument, also on failure.
19901992 if (filtermap != FILTERMAP_MAPNEW )
19911993 copy_tv (& argvars [0 ], rettv );
1994+ if (filtermap == FILTERMAP_MAP && in_vim9script ())
1995+ {
1996+ // Check that map() does not change the type of the dict.
1997+ ga_init2 (& type_list , sizeof (type_T * ), 10 );
1998+ type = typval2type (argvars , & type_list );
1999+ }
19922000
19932001 if (argvars [0 ].v_type == VAR_BLOB )
19942002 {
@@ -1998,7 +2006,7 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
19982006 rettv -> vval .v_blob = NULL ;
19992007 }
20002008 if ((b = argvars [0 ].vval .v_blob ) == NULL )
2001- return ;
2009+ goto theend ;
20022010 }
20032011 else if (argvars [0 ].v_type == VAR_LIST )
20042012 {
@@ -2010,7 +2018,7 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
20102018 if ((l = argvars [0 ].vval .v_list ) == NULL
20112019 || (filtermap == FILTERMAP_FILTER
20122020 && value_check_lock (l -> lv_lock , arg_errmsg , TRUE)))
2013- return ;
2021+ goto theend ;
20142022 }
20152023 else if (argvars [0 ].v_type == VAR_DICT )
20162024 {
@@ -2022,12 +2030,12 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
20222030 if ((d = argvars [0 ].vval .v_dict ) == NULL
20232031 || (filtermap == FILTERMAP_FILTER
20242032 && value_check_lock (d -> dv_lock , arg_errmsg , TRUE)))
2025- return ;
2033+ goto theend ;
20262034 }
20272035 else
20282036 {
20292037 semsg (_ (e_listdictblobarg ), ermsg );
2030- return ;
2038+ goto theend ;
20312039 }
20322040
20332041 expr = & argvars [1 ];
@@ -2055,7 +2063,7 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
20552063 if (filtermap == FILTERMAP_MAPNEW )
20562064 {
20572065 if (rettv_dict_alloc (rettv ) == FAIL )
2058- return ;
2066+ goto theend ;
20592067 d_ret = rettv -> vval .v_dict ;
20602068 }
20612069
@@ -2090,6 +2098,12 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
20902098 }
20912099 if (filtermap == FILTERMAP_MAP )
20922100 {
2101+ if (type != NULL && check_typval_type (type -> tt_member ,
2102+ & newtv , 0 ) == FAIL )
2103+ {
2104+ clear_tv (& newtv );
2105+ break ;
2106+ }
20932107 // map(): replace the dict item value
20942108 clear_tv (& di -> di_tv );
20952109 newtv .v_lock = 0 ;
@@ -2126,7 +2140,7 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
21262140 if (filtermap == FILTERMAP_MAPNEW )
21272141 {
21282142 if (blob_copy (b , rettv ) == FAIL )
2129- return ;
2143+ goto theend ;
21302144 b_ret = rettv -> vval .v_blob ;
21312145 }
21322146
@@ -2175,7 +2189,7 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
21752189 if (filtermap == FILTERMAP_MAPNEW )
21762190 {
21772191 if (rettv_list_alloc (rettv ) == FAIL )
2178- return ;
2192+ goto theend ;
21792193 l_ret = rettv -> vval .v_list ;
21802194 }
21812195 // set_vim_var_nr() doesn't set the type
@@ -2218,6 +2232,13 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
22182232 }
22192233 if (filtermap != FILTERMAP_FILTER )
22202234 {
2235+ if (filtermap == FILTERMAP_MAP && type != NULL
2236+ && check_typval_type (type -> tt_member ,
2237+ & newtv , 0 ) == FAIL )
2238+ {
2239+ clear_tv (& newtv );
2240+ break ;
2241+ }
22212242 // map(), mapnew(): always append the new value to the
22222243 // list
22232244 if (list_append_tv_move (filtermap == FILTERMAP_MAP
@@ -2256,6 +2277,12 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
22562277 }
22572278 if (filtermap == FILTERMAP_MAP )
22582279 {
2280+ if (type != NULL && check_typval_type (type -> tt_member ,
2281+ & newtv , 0 ) == FAIL )
2282+ {
2283+ clear_tv (& newtv );
2284+ break ;
2285+ }
22592286 // map(): replace the list item value
22602287 clear_tv (& li -> li_tv );
22612288 newtv .v_lock = 0 ;
@@ -2281,6 +2308,10 @@ filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
22812308
22822309 did_emsg |= save_did_emsg ;
22832310 }
2311+
2312+ theend :
2313+ if (type != NULL )
2314+ clear_type_list (& type_list );
22842315}
22852316
22862317/*
0 commit comments