From c1877d431e76f4a782d51602fa8487e98d302956 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Sun, 15 Jun 2025 09:11:01 -0700 Subject: [PATCH] [ruby/date] [Bug #21437] Date#hash for large years Addresses https://bugs.ruby-lang.org/issues/21437 Signed-off-by: Dmitry Dygalo https://github.com/ruby/date/commit/31f07bc576 --- ext/date/date_core.c | 21 ++++++++++++++++----- test/date/test_date.rb | 4 ++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 44dbf4fbcf..360f2fecdb 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -6936,13 +6936,24 @@ d_lite_eql_p(VALUE self, VALUE other) static VALUE d_lite_hash(VALUE self) { - st_index_t v, h[4]; + st_index_t v, h[5]; + VALUE nth; get_d1(self); - h[0] = m_nth(dat); - h[1] = m_jd(dat); - h[2] = m_df(dat); - h[3] = m_sf(dat); + nth = m_nth(dat); + + if (FIXNUM_P(nth)) { + h[0] = 0; + h[1] = (st_index_t)nth; + } else { + h[0] = 1; + h[1] = (st_index_t)FIX2LONG(rb_hash(nth)); + } + + h[2] = m_jd(dat); + h[3] = m_df(dat); + h[4] = m_sf(dat); + v = rb_memhash(h, sizeof(h)); return ST2FIX(v); } diff --git a/test/date/test_date.rb b/test/date/test_date.rb index 3f9c893efa..7e37fc94d2 100644 --- a/test/date/test_date.rb +++ b/test/date/test_date.rb @@ -134,6 +134,10 @@ class TestDate < Test::Unit::TestCase assert_equal(9, h[Date.new(1999,5,25)]) assert_equal(9, h[DateTime.new(1999,5,25)]) + h = {} + h[Date.new(3171505571716611468830131104691,2,19)] = 0 + assert_equal(true, h.key?(Date.new(3171505571716611468830131104691,2,19))) + h = {} h[DateTime.new(1999,5,23)] = 0 h[DateTime.new(1999,5,24)] = 1