# HG changeset patch # User Bram Moolenaar # Date 1640209503 -3600 # Node ID 1cee572f2fd7728d476e2cd687e44fb1c2fcc787 # Parent 221d727d6f9513b899833c2aa1f8741df2852919 patch 8.2.3877: function does not abort after a type error in compare Commit: https://github.com/vim/vim/commit/28fbbeac7046f33db350294908eecb380042d553 Author: Bram Moolenaar Date: Wed Dec 22 21:40:33 2021 +0000 patch 8.2.3877: function does not abort after a type error in compare Problem: Function does not abort after a type error in compare Solution: Check getting number fails. (closes https://github.com/vim/vim/issues/9384) diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -675,6 +675,36 @@ def Test_expr4_equal() CheckDefExecAndScriptFailure(["var x: any = true", 'echo x == ""'], 'E1072: Cannot compare bool with string', 2) CheckDefExecAndScriptFailure(["var x: any = 99", 'echo x == true'], ['E1138', 'E1072:'], 2) CheckDefExecAndScriptFailure(["var x: any = 'a'", 'echo x == 99'], ['E1030:', 'E1072:'], 2) + + lines =<< trim END + vim9script + var n: any = 2 + def Compare() + eval n == '3' + g:notReached = false + enddef + g:notReached = true + Compare() + END + CheckScriptFailure(lines, 'E1030: Using a String as a Number: "3"') + assert_true(g:notReached) + + if has('float') + lines =<< trim END + vim9script + var n: any = 2.2 + def Compare() + eval n == '3' + g:notReached = false + enddef + g:notReached = true + Compare() + END + CheckScriptFailure(lines, 'E892: Using a String as a Float') + assert_true(g:notReached) + endif + + unlet g:notReached enddef def Test_expr4_wrong_type() diff --git a/src/typval.c b/src/typval.c --- a/src/typval.c +++ b/src/typval.c @@ -297,8 +297,8 @@ tv_get_bool_chk(typval_T *varp, int *den } #if defined(FEAT_FLOAT) || defined(PROTO) - float_T -tv_get_float(typval_T *varp) + static float_T +tv_get_float_chk(typval_T *varp, int *error) { switch (varp->v_type) { @@ -347,8 +347,16 @@ tv_get_float(typval_T *varp) internal_error_no_abort("tv_get_float(UNKNOWN)"); break; } + if (error != NULL) + *error = TRUE; return 0; } + + float_T +tv_get_float(typval_T *varp) +{ + return tv_get_float_chk(varp, NULL); +} #endif /* @@ -1185,9 +1193,16 @@ typval_compare( && type != EXPR_MATCH && type != EXPR_NOMATCH) { float_T f1, f2; + int error = FALSE; - f1 = tv_get_float(tv1); - f2 = tv_get_float(tv2); + f1 = tv_get_float_chk(tv1, &error); + if (!error) + f2 = tv_get_float_chk(tv2, &error); + if (error) + { + clear_tv(tv1); + return FAIL; + } n1 = FALSE; switch (type) { @@ -1211,8 +1226,16 @@ typval_compare( else if ((tv1->v_type == VAR_NUMBER || tv2->v_type == VAR_NUMBER) && type != EXPR_MATCH && type != EXPR_NOMATCH) { - n1 = tv_get_number(tv1); - n2 = tv_get_number(tv2); + int error = FALSE; + + n1 = tv_get_number_chk(tv1, &error); + if (!error) + n2 = tv_get_number_chk(tv2, &error); + if (error) + { + clear_tv(tv1); + return FAIL; + } switch (type) { case EXPR_IS: diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3877, +/**/ 3876, /**/ 3875,