summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-26 18:26:21 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-26 18:26:21 +0000
commit1080c48ec8d672d7e9fbefb5a1255c9df09a2884 (patch)
tree78670ac28f61a47a4624b07f9144ed9e5c3a85f0
parent1a804528ab39f5c810cf42397702057100a94ade (diff)
downloadvim-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.c2
-rw-r--r--src/evalfunc.c64
-rw-r--r--src/testdir/test_vim9_builtin.vim2
-rw-r--r--src/version.c2
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,