To: vim_dev@googlegroups.com Subject: Patch 8.2.4224 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4224 Problem: Vim9: no error when using a number for map() second argument Solution: Disallow number to string conversion. (closes #9630) Files: src/eval.c, src/evalfunc.c, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.4223/src/eval.c 2022-01-26 16:45:16.934506694 +0000 --- src/eval.c 2022-01-26 17:37:24.284951289 +0000 *************** *** 291,297 **** } else { ! s = tv_get_string_buf_chk(expr, buf); if (s == NULL) return FAIL; s = skipwhite(s); --- 291,297 ---- } else { ! s = tv_get_string_buf_chk_strict(expr, buf, TRUE); if (s == NULL) return FAIL; s = skipwhite(s); *** ../vim-8.2.4223/src/evalfunc.c 2022-01-22 10:59:58.443950062 +0000 --- src/evalfunc.c 2022-01-26 18:23:45.687641629 +0000 *************** *** 491,503 **** static int arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { ! if (type->tt_type == VAR_FUNC ! && !(type->tt_member->tt_type == VAR_BOOL || type->tt_member->tt_type == VAR_NUMBER || type->tt_member->tt_type == VAR_UNKNOWN || type->tt_member->tt_type == VAR_ANY)) { ! arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1); return FAIL; } return OK; --- 491,516 ---- static int arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { ! if (type->tt_type == VAR_STRING ! || type->tt_type == VAR_PARTIAL ! || type == &t_unknown ! || type == &t_any) ! return OK; ! ! if (type->tt_type == VAR_FUNC) ! { ! if (!(type->tt_member->tt_type == VAR_BOOL || type->tt_member->tt_type == VAR_NUMBER || type->tt_member->tt_type == VAR_UNKNOWN || type->tt_member->tt_type == VAR_ANY)) + { + arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1); + return FAIL; + } + } + else { ! semsg(_(e_string_or_function_required_for_argument_nr), 2); return FAIL; } return OK; *************** *** 509,535 **** static int arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { ! if (type->tt_type == VAR_FUNC ! && type->tt_member != &t_any ! && type->tt_member != &t_unknown) ! { ! type_T *expected = NULL; ! if (context->arg_types[0].type_curr->tt_type == VAR_LIST ! || context->arg_types[0].type_curr->tt_type == VAR_DICT) ! expected = context->arg_types[0].type_curr->tt_member; ! else if (context->arg_types[0].type_curr->tt_type == VAR_STRING) ! expected = &t_string; ! else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB) ! expected = &t_number; ! if (expected != NULL) { ! type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, NULL, NULL}; ! t_func_exp.tt_member = expected; ! return check_arg_type(&t_func_exp, type, context); } } return OK; } --- 522,561 ---- static int arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) { ! if (type->tt_type == VAR_STRING ! || type->tt_type == VAR_PARTIAL ! || type == &t_unknown ! || type == &t_any) ! return OK; ! if (type->tt_type == VAR_FUNC) ! { ! if (type->tt_member != &t_any ! && type->tt_member != &t_unknown) { ! type_T *expected = NULL; ! ! if (context->arg_types[0].type_curr->tt_type == VAR_LIST ! || context->arg_types[0].type_curr->tt_type == VAR_DICT) ! expected = context->arg_types[0].type_curr->tt_member; ! else if (context->arg_types[0].type_curr->tt_type == VAR_STRING) ! expected = &t_string; ! else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB) ! expected = &t_number; ! if (expected != NULL) ! { ! type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, NULL, NULL}; ! t_func_exp.tt_member = expected; ! return check_arg_type(&t_func_exp, type, context); ! } } } + else + { + semsg(_(e_string_or_function_required_for_argument_nr), 2); + return FAIL; + } return OK; } *** ../vim-8.2.4223/src/testdir/test_vim9_builtin.vim 2022-01-18 21:42:33.836745971 +0000 --- src/testdir/test_vim9_builtin.vim 2022-01-26 18:17:10.087209666 +0000 *************** *** 1275,1280 **** --- 1275,1281 ---- def Test_filter() CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list but got float', 'E1251: List, Dictionary, Blob or String required for argument 1']) + CheckDefAndScriptFailure(['filter([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) var lines =<< trim END def F(i: number, v: any): string *************** *** 2153,2158 **** --- 2154,2160 ---- CheckDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list but got channel', 'E1251: List, Dictionary, Blob or String required for argument 1']) endif CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list but got number', 'E1251: List, Dictionary, Blob or String required for argument 1']) + CheckDefAndScriptFailure(['map([1, 2], 4)'], ['E1256: String or function required for argument 2', 'E1024: Using a Number as a String']) # type of dict remains dict even when type of values changes # same for list *** ../vim-8.2.4223/src/version.c 2022-01-26 16:45:16.934506694 +0000 --- src/version.c 2022-01-26 18:02:56.274980221 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4224, /**/ -- LETTERS TO THE EDITOR (The Times of London) Dear Sir, I am firmly opposed to the spread of microchips either to the home or to the office.  We have more than enough of them foisted upon us in public places.  They are a disgusting Americanism, and can only result in the farmers being forced to grow smaller potatoes, which in turn will cause massive unemployment in the already severely depressed agricultural industry. Yours faithfully,         Capt. Quinton D'Arcy, J. P.         Sevenoaks /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///