changeset 25545:08a0abcb46c1 v8.2.3309

patch 8.2.3309: Vim9: divide by zero causes a crash Commit: https://github.com/vim/vim/commit/fbeefb1b87b0d52a095c08fee47b62d290bf4c33 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 7 15:50:23 2021 +0200 patch 8.2.3309: Vim9: divide by zero causes a crash Problem: Vim9: divide by zero causes a crash. Solution: Give an error message. (closes https://github.com/vim/vim/issues/8727)
author Bram Moolenaar <Bram@vim.org>
date Sat, 07 Aug 2021 16:00:04 +0200
parents e40a94995183
children 465989ba8936
files src/testdir/test_vim9_expr.vim src/version.c src/vim9execute.c
diffstat 3 files changed, 34 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -1348,7 +1348,7 @@ enddef
 
 def Test_expr5_vim9script_channel()
   if !has('channel')
-    MissingFeature 'float'
+    MissingFeature 'channel'
   else
     var lines =<< trim END
         echo 'a' .. test_null_job()
@@ -1502,6 +1502,18 @@ def Test_expr6()
 
   CheckDefExecAndScriptFailure(['echo 1 / 0'], 'E1154', 1)
   CheckDefExecAndScriptFailure(['echo 1 % 0'], 'E1154', 1)
+
+  lines =<< trim END
+    var n = 0
+    eval 1 / n
+  END
+  CheckDefExecAndScriptFailure(lines, 'E1154', 2)
+
+  lines =<< trim END
+    var n = 0
+    eval 1 % n
+  END
+  CheckDefExecAndScriptFailure(lines, 'E1154', 2)
 enddef
 
 def Test_expr6_vim9script()
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3309,
+/**/
     3308,
 /**/
     3307,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -3435,13 +3435,22 @@ exec_instructions(ectx_T *ectx)
 		    typval_T	*tv2 = STACK_TV_BOT(-1);
 		    varnumber_T arg1 = tv1->vval.v_number;
 		    varnumber_T arg2 = tv2->vval.v_number;
-		    varnumber_T res;
+		    varnumber_T res = 0;
+		    int		div_zero = FALSE;
 
 		    switch (iptr->isn_arg.op.op_type)
 		    {
 			case EXPR_MULT: res = arg1 * arg2; break;
-			case EXPR_DIV: res = arg1 / arg2; break;
-			case EXPR_REM: res = arg1 % arg2; break;
+			case EXPR_DIV:  if (arg2 == 0)
+					    div_zero = TRUE;
+					else
+					    res = arg1 / arg2;
+					break;
+			case EXPR_REM:  if (arg2 == 0)
+					    div_zero = TRUE;
+					else
+					    res = arg1 % arg2;
+					break;
 			case EXPR_SUB: res = arg1 - arg2; break;
 			case EXPR_ADD: res = arg1 + arg2; break;
 
@@ -3451,7 +3460,7 @@ exec_instructions(ectx_T *ectx)
 			case EXPR_GEQUAL: res = arg1 >= arg2; break;
 			case EXPR_SMALLER: res = arg1 < arg2; break;
 			case EXPR_SEQUAL: res = arg1 <= arg2; break;
-			default: res = 0; break;
+			default: break;
 		    }
 
 		    --ectx->ec_stack.ga_len;
@@ -3462,6 +3471,12 @@ exec_instructions(ectx_T *ectx)
 		    }
 		    else
 			tv1->vval.v_number = res;
+		    if (div_zero)
+		    {
+			SOURCING_LNUM = iptr->isn_lnum;
+			emsg(_(e_divide_by_zero));
+			goto on_error;
+		    }
 		}
 		break;