changeset 26696:1cee572f2fd7 v8.2.3877

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 <Bram@vim.org> 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)
author Bram Moolenaar <Bram@vim.org>
date Wed, 22 Dec 2021 22:45:03 +0100
parents 221d727d6f95
children 052ba9029066
files src/testdir/test_vim9_expr.vim src/typval.c src/version.c
diffstat 3 files changed, 61 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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()
--- 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:
--- 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,