summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_time.rb5
-rw-r--r--time.c7
2 files changed, 11 insertions, 1 deletions
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index c629a59c02..b3dc5d99e3 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -386,6 +386,11 @@ class TestTime < Test::Unit::TestCase
end
end
+ def test_marshal_broken_month
+ data = "\x04\x08u:\tTime\r\x20\x7c\x1e\xc0\x00\x00\x00\x00"
+ assert_equal(Time.utc(2022, 4, 1), Marshal.load(data))
+ end
+
def test_marshal_distant_past
assert_marshal_roundtrip(Time.utc(1890, 1, 1))
assert_marshal_roundtrip(Time.utc(-4.5e9, 1, 1))
diff --git a/time.c b/time.c
index 9c23089cfd..8f044e1e59 100644
--- a/time.c
+++ b/time.c
@@ -5251,8 +5251,13 @@ time_mload(VALUE time, VALUE str)
year = rb_int_plus(year, year_extend);
}
}
+ unsigned int mon = ((int)(p >> 10) & 0xf); /* 0...12 */
+ if (mon >= 12) {
+ mon -= 12;
+ year = addv(year, LONG2FIX(1));
+ }
vtm.year = year;
- vtm.mon = ((int)(p >> 10) & 0xf) + 1;
+ vtm.mon = mon + 1;
vtm.mday = (int)(p >> 5) & 0x1f;
vtm.hour = (int) p & 0x1f;
vtm.min = (int)(s >> 26) & 0x3f;