diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-26 18:26:21 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-26 18:26:21 +0000 |
commit | 1080c48ec8d672d7e9fbefb5a1255c9df09a2884 (patch) | |
tree | 78670ac28f61a47a4624b07f9144ed9e5c3a85f0 | |
parent | 1a804528ab39f5c810cf42397702057100a94ade (diff) | |
download | vim-git-1080c48ec8d672d7e9fbefb5a1255c9df09a2884.tar.gz |
patch 8.2.4224: Vim9: no error when using a number for map() second argumentv8.2.4224
Problem: Vim9: no error when using a number for map() second argument
Solution: Disallow number to string conversion. (closes #9630)
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/evalfunc.c | 64 | ||||
-rw-r--r-- | src/testdir/test_vim9_builtin.vim | 2 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 50 insertions, 20 deletions
diff --git a/src/eval.c b/src/eval.c index 72b1d6c97..7bc37f237 100644 --- a/src/eval.c +++ b/src/eval.c @@ -291,7 +291,7 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) } else { - s = tv_get_string_buf_chk(expr, buf); + s = tv_get_string_buf_chk_strict(expr, buf, TRUE); if (s == NULL) return FAIL; s = skipwhite(s); diff --git a/src/evalfunc.c b/src/evalfunc.c index b838c395d..4376318d0 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -491,13 +491,26 @@ arg_list_or_dict_or_blob_or_string(type_T *type, type_T *decl_type UNUSED, argco 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 + 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 { - arg_type_mismatch(&t_func_bool, type, context->arg_idx + 1); + semsg(_(e_string_or_function_required_for_argument_nr), 2); return FAIL; } return OK; @@ -509,27 +522,40 @@ arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) 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 (type->tt_type == VAR_STRING + || type->tt_type == VAR_PARTIAL + || type == &t_unknown + || type == &t_any) + return OK; - 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) + if (type->tt_type == VAR_FUNC) + { + if (type->tt_member != &t_any + && type->tt_member != &t_unknown) { - type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, NULL, NULL}; + 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); + 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; } diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 3747a4e19..a00133f14 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -1275,6 +1275,7 @@ enddef def Test_filter() CheckDefAndScriptFailure(['filter(1.1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> 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,6 +2154,7 @@ def Test_map() CheckDefAndScriptFailure(['map(test_null_channel(), "1")'], ['E1013: Argument 1: type mismatch, expected list<any> 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<any> 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<any> even when type of values changes # same for list diff --git a/src/version.c b/src/version.c index e6f8b3a09..9869aa0d8 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4224, +/**/ 4223, /**/ 4222, |