comparison src/evalfunc.c @ 26737:10d3105030ab v8.2.3897

patch 8.2.3897: Vim9: second argument of map() and filter() not checked Commit: https://github.com/vim/vim/commit/1802405d71da20dff510690bf14f6da085836125 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Dec 25 21:43:28 2021 +0000 patch 8.2.3897: Vim9: second argument of map() and filter() not checked Problem: Vim9: the second argument of map() and filter() is not checked at compile time. Solution: Add more specific type check for the second argument.
author Bram Moolenaar <Bram@vim.org>
date Sat, 25 Dec 2021 22:45:02 +0100
parents 3aa38eaa5a11
children 59dde78e9436
comparison
equal deleted inserted replaced
26736:94a38e7f8ba9 26737:10d3105030ab
481 || type->tt_type == VAR_BLOB 481 || type->tt_type == VAR_BLOB
482 || type->tt_type == VAR_STRING) 482 || type->tt_type == VAR_STRING)
483 return OK; 483 return OK;
484 arg_type_mismatch(&t_list_any, type, context->arg_idx + 1); 484 arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
485 return FAIL; 485 return FAIL;
486 }
487
488 /*
489 * Check second argument of filter(): func must return a bool.
490 */
491 static int
492 arg_filter_func(type_T *type, argcontext_T *context)
493 {
494 if (type->tt_type == VAR_FUNC
495 && !(type->tt_member->tt_type == VAR_BOOL
496 || type->tt_member->tt_type == VAR_NUMBER
497 || type->tt_member->tt_type == VAR_ANY))
498 {
499 arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1);
500 return FAIL;
501 }
502 return OK;
503 }
504
505 /*
506 * Check second argument of map().
507 */
508 static int
509 arg_map_func(type_T *type, argcontext_T *context)
510 {
511 if (type->tt_type == VAR_FUNC
512 && type->tt_member != &t_any
513 && type->tt_member != &t_unknown)
514 {
515 type_T *expected = NULL;
516
517 if (context->arg_types[0]->tt_type == VAR_LIST
518 || context->arg_types[0]->tt_type == VAR_DICT)
519 expected = context->arg_types[0]->tt_member;
520 else if (context->arg_types[0]->tt_type == VAR_STRING
521 || context->arg_types[0]->tt_type == VAR_BLOB)
522 expected = &t_number;
523 if (expected != NULL)
524 {
525 type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC,
526 expected, NULL};
527
528 return check_arg_type(&t_func_exp, type, context);
529 }
530 }
531 return OK;
486 } 532 }
487 533
488 /* 534 /*
489 * Check "type" is a list of 'any' or a blob or a string. 535 * Check "type" is a list of 'any' or a blob or a string.
490 */ 536 */
857 static argcheck_T arg24_index[] = {arg_list_or_blob, arg_item_of_prev, arg_number, arg_bool}; 903 static argcheck_T arg24_index[] = {arg_list_or_blob, arg_item_of_prev, arg_number, arg_bool};
858 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; 904 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
859 static argcheck_T arg1_len[] = {arg_len1}; 905 static argcheck_T arg1_len[] = {arg_len1};
860 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr}; 906 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr};
861 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool}; 907 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
862 static argcheck_T arg2_mapfilter[] = {arg_list_or_dict_or_blob_or_string, NULL}; 908 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string, arg_filter_func};
909 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string, arg_map_func};
910 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, NULL};
863 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any}; 911 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
864 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any}; 912 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any};
865 static argcheck_T arg119_printf[] = {arg_string_or_nr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 913 static argcheck_T arg119_printf[] = {arg_string_or_nr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
866 static argcheck_T arg23_reduce[] = {arg_string_list_or_blob, NULL, NULL}; 914 static argcheck_T arg23_reduce[] = {arg_string_list_or_blob, NULL, NULL};
867 static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number}; 915 static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
1435 ret_number_bool, f_filereadable}, 1483 ret_number_bool, f_filereadable},
1436 {"filereadable", 1, 1, FEARG_1, arg1_string, 1484 {"filereadable", 1, 1, FEARG_1, arg1_string,
1437 ret_number_bool, f_filereadable}, 1485 ret_number_bool, f_filereadable},
1438 {"filewritable", 1, 1, FEARG_1, arg1_string, 1486 {"filewritable", 1, 1, FEARG_1, arg1_string,
1439 ret_number, f_filewritable}, 1487 ret_number, f_filewritable},
1440 {"filter", 2, 2, FEARG_1, arg2_mapfilter, 1488 {"filter", 2, 2, FEARG_1, arg2_filter,
1441 ret_first_arg, f_filter}, 1489 ret_first_arg, f_filter},
1442 {"finddir", 1, 3, FEARG_1, arg3_string_string_number, 1490 {"finddir", 1, 3, FEARG_1, arg3_string_string_number,
1443 ret_finddir, f_finddir}, 1491 ret_finddir, f_finddir},
1444 {"findfile", 1, 3, FEARG_1, arg3_string_string_number, 1492 {"findfile", 1, 3, FEARG_1, arg3_string_string_number,
1445 ret_any, f_findfile}, 1493 ret_any, f_findfile},
1701 f_luaeval 1749 f_luaeval
1702 #else 1750 #else
1703 NULL 1751 NULL
1704 #endif 1752 #endif
1705 }, 1753 },
1706 {"map", 2, 2, FEARG_1, arg2_mapfilter, 1754 {"map", 2, 2, FEARG_1, arg2_map,
1707 ret_first_cont, f_map}, 1755 ret_first_cont, f_map},
1708 {"maparg", 1, 4, FEARG_1, arg14_maparg, 1756 {"maparg", 1, 4, FEARG_1, arg14_maparg,
1709 ret_maparg, f_maparg}, 1757 ret_maparg, f_maparg},
1710 {"mapcheck", 1, 3, FEARG_1, arg3_string_string_bool, 1758 {"mapcheck", 1, 3, FEARG_1, arg3_string_string_bool,
1711 ret_string, f_mapcheck}, 1759 ret_string, f_mapcheck},
1712 {"mapnew", 2, 2, FEARG_1, arg2_mapfilter, 1760 {"mapnew", 2, 2, FEARG_1, arg2_mapnew,
1713 ret_first_cont, f_mapnew}, 1761 ret_first_cont, f_mapnew},
1714 {"mapset", 3, 3, FEARG_1, arg3_string_bool_dict, 1762 {"mapset", 3, 3, FEARG_1, arg3_string_bool_dict,
1715 ret_void, f_mapset}, 1763 ret_void, f_mapset},
1716 {"match", 2, 4, FEARG_1, arg24_match_func, 1764 {"match", 2, 4, FEARG_1, arg24_match_func,
1717 ret_any, f_match}, 1765 ret_any, f_match},