From 543e6f3467f208930a5d7fadb82133334bf31356 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar <Bram@vim.org> Date: Fri, 10 Jul 2020 22:45:38 +0200 Subject: [PATCH] patch 8.2.1176: Vim9: not enough type checking in Vim9 script Problem: Vim9: not enough type checking in Vim9 script. Solution: Use same type checking as in a :def function. --- src/eval.c | 10 +++++++++- src/proto/vim9compile.pro | 1 + src/testdir/test_vim9_expr.vim | 21 ++++++++++++++++++++- src/version.c | 2 ++ src/vim9compile.c | 10 +++++++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/eval.c b/src/eval.c index 6a1bc4c7a0..595cd06663 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2460,8 +2460,16 @@ eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg) } if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE)) { - int ret = typval_compare(rettv, &var2, type, ic); + int ret; + if (in_vim9script() && check_compare_types( + type, rettv, &var2) == FAIL) + { + ret = FAIL; + clear_tv(rettv); + } + else + ret = typval_compare(rettv, &var2, type, ic); clear_tv(&var2); return ret; } diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro index 5486bd9236..03862a271b 100644 --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -3,6 +3,7 @@ int check_defined(char_u *p, size_t len, cctx_T *cctx); void clear_type_list(garray_T *gap); type_T *typval2type(typval_T *tv); int check_type(type_T *expected, type_T *actual, int give_msg); +int check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2); char_u *skip_type(char_u *start); type_T *parse_type(char_u **arg, garray_T *type_gap); char *vartype_name(vartype_T type); diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 1f4bde9123..ef56a67111 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -557,7 +557,7 @@ def RetVoid() enddef def Test_expr4_vimscript() - " only checks line continuation + " check line continuation let lines =<< trim END vim9script let var = 0 @@ -599,6 +599,25 @@ def Test_expr4_vimscript() assert_equal(1, var) END CheckScriptSuccess(lines) + + " spot check mismatching types + lines =<< trim END + vim9script + echo '' == 0 + END + CheckScriptFailure(lines, 'E1072:') + + lines =<< trim END + vim9script + echo v:true > v:false + END + CheckScriptFailure(lines, 'Cannot compare bool with bool') + + lines =<< trim END + vim9script + echo 123 is 123 + END + CheckScriptFailure(lines, 'Cannot use "is" with number') enddef func Test_expr4_fails() diff --git a/src/version.c b/src/version.c index ac5425ddd5..6c6211da1a 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1176, /**/ 1175, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 3c0336ac4a..e7f90e1c7f 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -820,6 +820,14 @@ get_compare_isn(exptype_T exptype, vartype_T type1, vartype_T type2) return isntype; } + int +check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2) +{ + if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP) + return FAIL; + return OK; +} + /* * Generate an ISN_COMPARE* instruction with a boolean result. */ @@ -4296,7 +4304,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) // Both sides are a constant, compute the result now. // First check for a valid combination of types, this is more // strict than typval_compare(). - if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP) + if (check_compare_types(type, tv1, tv2) == FAIL) ret = FAIL; else { -- GitLab