ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:122516] [Ruby Bug#21437] Date#hash may return different values for equal dates with large years
@ 2025-06-11 12:50 Stranger6667 (Dmitry Dygalo) via ruby-core
  2025-06-29  3:39 ` [ruby-core:122617] " nagachika (Tomoyuki Chikanaga) via ruby-core
  0 siblings, 1 reply; 2+ messages in thread
From: Stranger6667 (Dmitry Dygalo) via ruby-core @ 2025-06-11 12:50 UTC (permalink / raw)
  To: ruby-core; +Cc: Stranger6667 (Dmitry Dygalo)

Issue #21437 has been reported by Stranger6667 (Dmitry Dygalo).

----------------------------------------
Bug #21437: Date#hash may return different values for equal dates with large years
https://bugs.ruby-lang.org/issues/21437

* Author: Stranger6667 (Dmitry Dygalo)
* Status: Open
* ruby -v: 3.2.8 - 3.4.4 (and older versions too)
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
Parsing the same date string allocates new large integer objects with different pointer addresses, which then affects the hash value due to `d_lite_hash` behavior.

```ruby
require 'date'

# Small year - consistent hashes
Date.strptime('2024-5-9', '%Y-%m-%d').hash
#=> 3287407234087466140
Date.strptime('2024-5-9', '%Y-%m-%d').hash  
#=> 3287407234087466140

# BUG - Large year - different hashes for identical date strings
Date.strptime('3171505571716611468830131104691-5-9', '%Y-%m-%d').hash
#=> 3525034678868094350
Date.strptime('3171505571716611468830131104691-5-9', '%Y-%m-%d').hash
#=> 2502076152602341316  # Different hash for same date!
```

In [ext/date/date_core.c](https://github.com/ruby/ruby/blob/v3_4_4/ext/date/date_core.c#L6936):

```c
static VALUE
d_lite_hash(VALUE self)
{
    st_index_t v, h[4];
    get_d1(self);
    h[0] = m_nth(dat);  // Could be different for equal large integers
    // ...
    v = rb_memhash(h, sizeof(h));
    return ST2FIX(v);
}
```

Each call to `Date.strptime` with a large year allocates a new large integer for `m_nth(dat)`. The hash function uses this pointer address directly in `rb_memhash`, so equal dates parsed separately get different hashes.

This breaks the hash contract that equal objects must have equal hashes.



-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [ruby-core:122617] [Ruby Bug#21437] Date#hash may return different values for equal dates with large years
  2025-06-11 12:50 [ruby-core:122516] [Ruby Bug#21437] Date#hash may return different values for equal dates with large years Stranger6667 (Dmitry Dygalo) via ruby-core
@ 2025-06-29  3:39 ` nagachika (Tomoyuki Chikanaga) via ruby-core
  0 siblings, 0 replies; 2+ messages in thread
From: nagachika (Tomoyuki Chikanaga) via ruby-core @ 2025-06-29  3:39 UTC (permalink / raw)
  To: ruby-core; +Cc: nagachika (Tomoyuki Chikanaga)

Issue #21437 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 3.2: WONTFIX, 3.3: REQUIRED, 3.4: REQUIRED to 3.2: WONTFIX, 3.3: DONE, 3.4: REQUIRED

ruby_3_3 commit:1fb5ab411f618f651926ecae9427605e03e19884 merged revision(s) commit:c1877d431e76f4a782d51602fa8487e98d302956.

----------------------------------------
Bug #21437: Date#hash may return different values for equal dates with large years
https://bugs.ruby-lang.org/issues/21437#change-113856

* Author: Stranger6667 (Dmitry Dygalo)
* Status: Closed
* ruby -v: 3.2.8 - 3.4.4 (and older versions too)
* Backport: 3.2: WONTFIX, 3.3: DONE, 3.4: REQUIRED
----------------------------------------
Parsing the same date string allocates new large integer objects with different pointer addresses, which then affects the hash value due to `d_lite_hash` behavior.

```ruby
require 'date'

# Small year - consistent hashes
Date.strptime('2024-5-9', '%Y-%m-%d').hash
#=> 3287407234087466140
Date.strptime('2024-5-9', '%Y-%m-%d').hash  
#=> 3287407234087466140

# BUG - Large year - different hashes for identical date strings
Date.strptime('3171505571716611468830131104691-5-9', '%Y-%m-%d').hash
#=> 3525034678868094350
Date.strptime('3171505571716611468830131104691-5-9', '%Y-%m-%d').hash
#=> 2502076152602341316  # Different hash for same date!
```

In [ext/date/date_core.c](https://github.com/ruby/ruby/blob/v3_4_4/ext/date/date_core.c#L6936):

```c
static VALUE
d_lite_hash(VALUE self)
{
    st_index_t v, h[4];
    get_d1(self);
    h[0] = m_nth(dat);  // Could be different for equal large integers
    // ...
    v = rb_memhash(h, sizeof(h));
    return ST2FIX(v);
}
```

The hash function uses this pointer address directly in `rb_memhash`, so equal dates parsed separately get different hashes.

This breaks the hash contract that equal objects must have equal hashes.



-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-06-29  3:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-11 12:50 [ruby-core:122516] [Ruby Bug#21437] Date#hash may return different values for equal dates with large years Stranger6667 (Dmitry Dygalo) via ruby-core
2025-06-29  3:39 ` [ruby-core:122617] " nagachika (Tomoyuki Chikanaga) via ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).