Mercurial > vim
comparison src/vim9execute.c @ 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 | a84e75d73fde |
children | ea69398b40d1 |
comparison
equal
deleted
inserted
replaced
25544:e40a94995183 | 25545:08a0abcb46c1 |
---|---|
3433 { | 3433 { |
3434 typval_T *tv1 = STACK_TV_BOT(-2); | 3434 typval_T *tv1 = STACK_TV_BOT(-2); |
3435 typval_T *tv2 = STACK_TV_BOT(-1); | 3435 typval_T *tv2 = STACK_TV_BOT(-1); |
3436 varnumber_T arg1 = tv1->vval.v_number; | 3436 varnumber_T arg1 = tv1->vval.v_number; |
3437 varnumber_T arg2 = tv2->vval.v_number; | 3437 varnumber_T arg2 = tv2->vval.v_number; |
3438 varnumber_T res; | 3438 varnumber_T res = 0; |
3439 int div_zero = FALSE; | |
3439 | 3440 |
3440 switch (iptr->isn_arg.op.op_type) | 3441 switch (iptr->isn_arg.op.op_type) |
3441 { | 3442 { |
3442 case EXPR_MULT: res = arg1 * arg2; break; | 3443 case EXPR_MULT: res = arg1 * arg2; break; |
3443 case EXPR_DIV: res = arg1 / arg2; break; | 3444 case EXPR_DIV: if (arg2 == 0) |
3444 case EXPR_REM: res = arg1 % arg2; break; | 3445 div_zero = TRUE; |
3446 else | |
3447 res = arg1 / arg2; | |
3448 break; | |
3449 case EXPR_REM: if (arg2 == 0) | |
3450 div_zero = TRUE; | |
3451 else | |
3452 res = arg1 % arg2; | |
3453 break; | |
3445 case EXPR_SUB: res = arg1 - arg2; break; | 3454 case EXPR_SUB: res = arg1 - arg2; break; |
3446 case EXPR_ADD: res = arg1 + arg2; break; | 3455 case EXPR_ADD: res = arg1 + arg2; break; |
3447 | 3456 |
3448 case EXPR_EQUAL: res = arg1 == arg2; break; | 3457 case EXPR_EQUAL: res = arg1 == arg2; break; |
3449 case EXPR_NEQUAL: res = arg1 != arg2; break; | 3458 case EXPR_NEQUAL: res = arg1 != arg2; break; |
3450 case EXPR_GREATER: res = arg1 > arg2; break; | 3459 case EXPR_GREATER: res = arg1 > arg2; break; |
3451 case EXPR_GEQUAL: res = arg1 >= arg2; break; | 3460 case EXPR_GEQUAL: res = arg1 >= arg2; break; |
3452 case EXPR_SMALLER: res = arg1 < arg2; break; | 3461 case EXPR_SMALLER: res = arg1 < arg2; break; |
3453 case EXPR_SEQUAL: res = arg1 <= arg2; break; | 3462 case EXPR_SEQUAL: res = arg1 <= arg2; break; |
3454 default: res = 0; break; | 3463 default: break; |
3455 } | 3464 } |
3456 | 3465 |
3457 --ectx->ec_stack.ga_len; | 3466 --ectx->ec_stack.ga_len; |
3458 if (iptr->isn_type == ISN_COMPARENR) | 3467 if (iptr->isn_type == ISN_COMPARENR) |
3459 { | 3468 { |
3460 tv1->v_type = VAR_BOOL; | 3469 tv1->v_type = VAR_BOOL; |
3461 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE; | 3470 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE; |
3462 } | 3471 } |
3463 else | 3472 else |
3464 tv1->vval.v_number = res; | 3473 tv1->vval.v_number = res; |
3474 if (div_zero) | |
3475 { | |
3476 SOURCING_LNUM = iptr->isn_lnum; | |
3477 emsg(_(e_divide_by_zero)); | |
3478 goto on_error; | |
3479 } | |
3465 } | 3480 } |
3466 break; | 3481 break; |
3467 | 3482 |
3468 // Computation with two float arguments | 3483 // Computation with two float arguments |
3469 case ISN_OPFLOAT: | 3484 case ISN_OPFLOAT: |