diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-12-24 23:17:18 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-12-24 23:17:18 +0900 |
| commit | 2850b58dd98dad75158326eb5e8318f65630fe7e (patch) | |
| tree | 847cb1f7e1f48fc629a607b423909579785ed98b /src | |
| parent | 3419426dbf8086a933097175970d4fa585b1d1ef (diff) | |
| download | mruby-2850b58dd98dad75158326eb5e8318f65630fe7e.tar.gz mruby-2850b58dd98dad75158326eb5e8318f65630fe7e.zip | |
Check integer overflow in float bit operations.
Diffstat (limited to 'src')
| -rw-r--r-- | src/numeric.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/numeric.c b/src/numeric.c index 2eb5e0ff1..117f447e5 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -484,7 +484,12 @@ value_int64(mrb_state *mrb, mrb_value x) case MRB_TT_INTEGER: return (int64_t)mrb_integer(x); case MRB_TT_FLOAT: - return (int64_t)mrb_float(x); + { + double f = mrb_float(x); + + if ((mrb_float)INT64_MAX >= f && f >= (mrb_float)INT64_MIN) + return (int64_t)f; + } default: mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer"); break; @@ -496,17 +501,16 @@ value_int64(mrb_state *mrb, mrb_value x) static mrb_value int64_value(mrb_state *mrb, int64_t v) { - if (TYPED_FIXABLE(v,int64_t)) { - return mrb_fixnum_value((mrb_int)v); + if (!TYPED_FIXABLE(v,int64_t)) { + int_overflow(mrb, "bit operation"); } - return mrb_float_value(mrb, (mrb_float)v); + return mrb_fixnum_value((mrb_int)v); } static mrb_value flo_rev(mrb_state *mrb, mrb_value x) { - int64_t v1; - v1 = (int64_t)mrb_float(x); + int64_t v1 = value_int64(mrb, x); return int64_value(mrb, ~v1); } @@ -516,7 +520,7 @@ flo_and(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); int64_t v1, v2; - v1 = (int64_t)mrb_float(x); + v1 = value_int64(mrb, x); v2 = value_int64(mrb, y); return int64_value(mrb, v1 & v2); } @@ -527,7 +531,7 @@ flo_or(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); int64_t v1, v2; - v1 = (int64_t)mrb_float(x); + v1 = value_int64(mrb, x); v2 = value_int64(mrb, y); return int64_value(mrb, v1 | v2); } @@ -538,7 +542,7 @@ flo_xor(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); int64_t v1, v2; - v1 = (int64_t)mrb_float(x); + v1 = value_int64(mrb, x); v2 = value_int64(mrb, y); return int64_value(mrb, v1 ^ v2); } |
