From 7ab3f98604a05d12d0323414db008b3938981e08 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 7 Mar 2018 08:07:24 +0000 Subject: date_core.c: check conversion * ext/date/date_core.c (offset_to_sec, d_lite_plus): check conversion results, to get rid of infinite recursion. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62685 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/date/date_core.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'ext') diff --git a/ext/date/date_core.c b/ext/date/date_core.c index e214a65f46..5fc5053f88 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -2333,6 +2333,9 @@ VALUE date_zone_to_diff(VALUE); static int offset_to_sec(VALUE vof, int *rof) { + int try_rational = 1; + + again: switch (TYPE(vof)) { case T_FIXNUM: { @@ -2359,10 +2362,11 @@ offset_to_sec(VALUE vof, int *rof) default: expect_numeric(vof); vof = f_to_r(vof); -#ifdef CANONICALIZATION_FOR_MATHN - if (!k_rational_p(vof)) - return offset_to_sec(vof, rof); -#endif + if (!k_rational_p(vof)) { + if (!try_rational) Check_Type(vof, T_RATIONAL); + try_rational = 0; + goto again; + } /* fall through */ case T_RATIONAL: { @@ -2371,17 +2375,10 @@ offset_to_sec(VALUE vof, int *rof) vs = day_to_sec(vof); -#ifdef CANONICALIZATION_FOR_MATHN if (!k_rational_p(vs)) { - if (!FIXNUM_P(vs)) - return 0; - n = FIX2LONG(vs); - if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS) - return 0; - *rof = (int)n; - return 1; + vn = vs; + goto rounded; } -#endif vn = rb_rational_num(vs); vd = rb_rational_den(vs); @@ -2391,6 +2388,7 @@ offset_to_sec(VALUE vof, int *rof) vn = f_round(vs); if (!f_eqeq_p(vn, vs)) rb_warning("fraction of offset is ignored"); + rounded: if (!FIXNUM_P(vn)) return 0; n = FIX2LONG(vn); @@ -5513,8 +5511,10 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self) static VALUE d_lite_plus(VALUE self, VALUE other) { + int try_rational = 1; get_d1(self); + again: switch (TYPE(other)) { case T_FIXNUM: { @@ -5724,18 +5724,21 @@ d_lite_plus(VALUE self, VALUE other) default: expect_numeric(other); other = f_to_r(other); -#ifdef CANONICALIZATION_FOR_MATHN - if (!k_rational_p(other)) - return d_lite_plus(self, other); -#endif + if (!k_rational_p(other)) { + if (!try_rational) Check_Type(other, T_RATIONAL); + try_rational = 0; + goto again; + } /* fall through */ case T_RATIONAL: { VALUE nth, sf, t; int jd, df, s; - if (wholenum_p(other)) - return d_lite_plus(self, rb_rational_num(other)); + if (wholenum_p(other)) { + other = rb_rational_num(other); + goto again; + } if (f_positive_p(other)) s = +1; -- cgit v1.2.3