summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-08-07 15:50:23 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-07 15:50:23 +0200
commitfbeefb1b87b0d52a095c08fee47b62d290bf4c33 (patch)
tree53199e5c2f7181dc6dd4b85ac8f744aef02aa497
parent6ce46b99635877fb0a17c06a6f5625fbc1ffa6f4 (diff)
patch 8.2.3309: Vim9: divide by zero causes a crashv8.2.3309
Problem: Vim9: divide by zero causes a crash. Solution: Give an error message. (closes #8727)
-rw-r--r--src/testdir/test_vim9_expr.vim14
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c23
3 files changed, 34 insertions, 5 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index f207056fc3..11e152407f 100644
--- 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()
diff --git a/src/version.c b/src/version.c
index 867d894a2f..97823dfd8f 100644
--- 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,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index b728815127..e6ba700787 100644
--- 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;