summaryrefslogtreecommitdiffhomepage
path: root/src/numeric.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-08-07 10:51:33 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-08-07 10:51:33 +0900
commitd8e060d2d3391b734f40b812651a171762de1c3b (patch)
tree994a02380e45938ab20af9a168df42d7dd6183a2 /src/numeric.c
parent9742bce1988b02b93fe79226c3f2e5d8091e4513 (diff)
downloadmruby-d8e060d2d3391b734f40b812651a171762de1c3b.tar.gz
mruby-d8e060d2d3391b734f40b812651a171762de1c3b.zip
Avoid `division by zero` undefined behavior.
Diffstat (limited to 'src/numeric.c')
-rw-r--r--src/numeric.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/numeric.c b/src/numeric.c
index 49d30c1a5..ae05170be 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -149,20 +149,28 @@ integral_idiv(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-integral_div(mrb_state *mrb, mrb_value x)
+integral_div(mrb_state *mrb, mrb_value xv)
{
#ifdef MRB_WITHOUT_FLOAT
- mrb_value y = mrb_get_arg1(mrb);
+ mrb_int y;
- if (!mrb_fixnum_p(y)) {
- mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
+ mrb_get_args(mrb, "i", &y);
+ if (y == 0) {
+ mrb_raise(mrb, E_RUNTIME_ERROR, "devided by zero");
}
- return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
+ return mrb_float_value(mrb, mrb_fixnum(xv) / y);
#else
- mrb_float y;
+ mrb_float x, y;
mrb_get_args(mrb, "f", &y);
- return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
+ x = mrb_to_flo(mrb, xv);
+ if (y == 0) {
+ if (x < 0)
+ return mrb_float_value(mrb, -INFINITY);
+ else
+ return mrb_float_value(mrb, INFINITY);
+ }
+ return mrb_float_value(mrb, x / y);
#endif
}
@@ -883,7 +891,7 @@ fix_mod(mrb_state *mrb, mrb_value x)
mrb_int a, b;
a = mrb_fixnum(x);
- if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) {
+ if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) {
mrb_int mod;
if (b == 0) {