Mercurial > vim
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}, |