diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-16 15:32:54 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-01-16 15:32:54 +0000 |
commit | 11a64cea0a4c5e72611c40fc92fe9ac0889cd662 (patch) | |
tree | e53ce6a15fc830025869065541765a19edb5a225 | |
parent | 9ab19d792e8fa412900ad671256ba5ee49730f21 (diff) |
merge revision(s) 65974: [Backport #15340]
Normalize month-mday before finding epoch
Especially over the year 2038, 30 Feb and so on may cause odd behavior
on validating found epoch with given year-month-day [Bug #15340]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@66839 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | test/ruby/test_time.rb | 23 | ||||
-rw-r--r-- | time.c | 23 | ||||
-rw-r--r-- | version.h | 6 |
3 files changed, 49 insertions, 3 deletions
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb index faeff8ded3..5ddcc9dcfe 100644 --- a/test/ruby/test_time.rb +++ b/test/ruby/test_time.rb @@ -1056,6 +1056,29 @@ class TestTime < Test::Unit::TestCase assert_equal(min, t.min) assert_equal(sec, t.sec) } + assert_equal(Time.local(2038,3,1), Time.local(2038,2,29)) + assert_equal(Time.local(2038,3,2), Time.local(2038,2,30)) + assert_equal(Time.local(2038,3,3), Time.local(2038,2,31)) + assert_equal(Time.local(2040,2,29), Time.local(2040,2,29)) + assert_equal(Time.local(2040,3,1), Time.local(2040,2,30)) + assert_equal(Time.local(2040,3,2), Time.local(2040,2,31)) + n = 2 ** 64 + n += 400 - n % 400 # n is over 2^64 and multiple of 400 + assert_equal(Time.local(n,2,29),Time.local(n,2,29)) + assert_equal(Time.local(n,3,1), Time.local(n,2,30)) + assert_equal(Time.local(n,3,2), Time.local(n,2,31)) + n += 100 + assert_equal(Time.local(n,3,1), Time.local(n,2,29)) + assert_equal(Time.local(n,3,2), Time.local(n,2,30)) + assert_equal(Time.local(n,3,3), Time.local(n,2,31)) + n += 4 + assert_equal(Time.local(n,2,29),Time.local(n,2,29)) + assert_equal(Time.local(n,3,1), Time.local(n,2,30)) + assert_equal(Time.local(n,3,2), Time.local(n,2,31)) + n += 1 + assert_equal(Time.local(n,3,1), Time.local(n,2,29)) + assert_equal(Time.local(n,3,2), Time.local(n,2,30)) + assert_equal(Time.local(n,3,3), Time.local(n,2,31)) end def test_future @@ -2610,6 +2610,29 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm) vtm->mday = obj2ubits(v[2], 5); } + /* normalize month-mday */ + switch (vtm->mon) { + case 2: + { + /* this drops higher bits but it's not a problem to calc leap year */ + unsigned int mday2 = leap_year_v_p(vtm->year) ? 29 : 28; + if (vtm->mday > mday2) { + vtm->mday -= mday2; + vtm->mon++; + } + } + break; + case 4: + case 6: + case 9: + case 11: + if (vtm->mday == 31) { + vtm->mon++; + vtm->mday = 1; + } + break; + } + vtm->hour = NIL_P(v[3])?0:obj2ubits(v[3], 5); vtm->min = NIL_P(v[4])?0:obj2ubits(v[4], 6); @@ -1,10 +1,10 @@ #define RUBY_VERSION "2.5.4" -#define RUBY_RELEASE_DATE "2019-01-16" -#define RUBY_PATCHLEVEL 130 +#define RUBY_RELEASE_DATE "2019-01-17" +#define RUBY_PATCHLEVEL 131 #define RUBY_RELEASE_YEAR 2019 #define RUBY_RELEASE_MONTH 1 -#define RUBY_RELEASE_DAY 16 +#define RUBY_RELEASE_DAY 17 #include "ruby/version.h" |