ruby-changes:50545
From: nobu <ko1@a...>
Date: Wed, 7 Mar 2018 17:07:29 +0900 (JST)
Subject: [ruby-changes:50545] nobu:r62685 (trunk): date_core.c: check conversion
nobu 2018-03-07 17:07:24 +0900 (Wed, 07 Mar 2018) New Revision: 62685 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62685 Log: 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. Modified files: trunk/ext/date/date_core.c trunk/test/date/test_date_arith.rb Index: ext/date/date_core.c =================================================================== --- ext/date/date_core.c (revision 62684) +++ ext/date/date_core.c (revision 62685) @@ -2333,6 +2333,9 @@ VALUE date_zone_to_diff(VALUE); https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L2333 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L2362 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L2375 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L2388 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, https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L5511 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L5724 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; Index: test/date/test_date_arith.rb =================================================================== --- test/date/test_date_arith.rb (revision 62684) +++ test/date/test_date_arith.rb (revision 62685) @@ -3,11 +3,18 @@ require 'test/unit' https://github.com/ruby/ruby/blob/trunk/test/date/test_date_arith.rb#L3 require 'date' class TestDateArith < Test::Unit::TestCase + class Rat < Numeric + def to_r; self; end + end def test_new_offset d = DateTime.new(2002, 3, 14) assert_equal(Rational(9, 24), d.new_offset(Rational(9, 24)).offset) assert_equal(Rational(9, 24), d.new_offset('+0900').offset) + n = Rat.new + assert_raise(TypeError) do + Timeout.timeout(1) {d.new_offset(n)} + end end def test__plus @@ -37,6 +44,13 @@ class TestDateArith < Test::Unit::TestCa https://github.com/ruby/ruby/blob/trunk/test/date/test_date_arith.rb#L44 assert_raise(e) do DateTime.new(2000,2,29) + Time.mktime(2000,2,29) end + n = Rat.new + assert_raise(e) do + Timeout.timeout(1) {Date.new(2000,2,29) + n} + end + assert_raise(e) do + Timeout.timeout(1) {DateTime.new(2000,2,29) + n} + end end def test__minus -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/