From 65add8c650088f398642aa9611baf4cb2266fff4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 1 Mar 2021 07:56:11 +0900 Subject: time.c: avoid using `mrb_int_{add,sub}_overflow()`. The size and signedness of `mrb_int` and `time_t` may differ. --- mrbgems/mruby-time/src/time.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 0a8b30233..fcd5902e0 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -556,6 +556,12 @@ mrb_time_cmp(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(0); } +static mrb_noreturn void +int_overflow(mrb_state *mrb, const char *reason) +{ + mrb_raisef(mrb, E_RANGE_ERROR, "time_t overflow in Time %s", reason); +} + static mrb_value mrb_time_plus(mrb_state *mrb, mrb_value self) { @@ -565,9 +571,22 @@ mrb_time_plus(mrb_state *mrb, mrb_value self) tm = time_get_ptr(mrb, self); sec = mrb_to_time_t(mrb, o, &usec); - if (mrb_int_add_overflow(tm->sec, sec, &sec)) { - mrb_raise(mrb, E_RANGE_ERROR, "time_t overflow in Time"); +#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS + if (__builtin_add_overflow(tm->sec, sec, &sec)) { + int_overflow(mrb, "addition"); + } +#else + if (sec >= 0) { + if (tm->sec > MRB_TIME_MAX - sec) { + int_overflow(mrb, "addition"); + } + } + else { + if (tm->sec < MRB_TIME_MIN - sec) { + int_overflow(mrb, "addition"); + } } +#endif return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec+usec, tm->timezone); } @@ -595,9 +614,22 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) else { time_t sec, usec; sec = mrb_to_time_t(mrb, other, &usec); - if (mrb_int_sub_overflow(tm->sec, sec, &sec)) { - mrb_raise(mrb, E_RANGE_ERROR, "time_t overflow in Time"); +#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS + if (__builtin_sub_overflow(tm->sec, sec, &sec)) { + int_overflow(mrb, "subtraction"); + } +#else + if (sec >= 0) { + if (tm->sec < MRB_TIME_MIN + sec) { + int_overflow(mrb, "subtraction"); + } } + else { + if (tm->sec > MRB_TIME_MAX + sec) { + int_overflow(mrb, "subtraction"); + } + } +#endif return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec-usec, tm->timezone); } } -- cgit v1.2.3