ruby-changes:64874
From: Nobuyoshi <ko1@a...>
Date: Thu, 14 Jan 2021 11:22:07 +0900 (JST)
Subject: [ruby-changes:64874] b2beb8586e (ruby_3_0): Make any hash values fixable [Bug #17488]
https://git.ruby-lang.org/ruby.git/commit/?id=b2beb8586e From b2beb8586e930c168af434d6545f75d76123192b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Thu, 31 Dec 2020 08:39:20 +0900 Subject: Make any hash values fixable [Bug #17488] As hnum is an unsigned st_index_t, the result of RSHIFT may not be in the fixable range. Co-authored-by: NeoCat <neocat@n...> diff --git a/hash.c b/hash.c index c3a512b..0ed2692 100644 --- a/hash.c +++ b/hash.c @@ -223,15 +223,10 @@ any_hash(VALUE a, st_index_t (*other_func)(VALUE)) https://github.com/ruby/ruby/blob/trunk/hash.c#L223 default: hnum = other_func(a); } -#if SIZEOF_LONG < SIZEOF_ST_INDEX_T - if (hnum > 0) - hnum &= (unsigned long)-1 >> 2; + if ((SIGNED_VALUE)hnum > 0) + hnum &= FIXNUM_MAX; else - hnum |= ~((unsigned long)-1 >> 2); -#else - hnum <<= 1; - hnum = RSHIFT(hnum, 1); -#endif + hnum |= FIXNUM_MIN; return (long)hnum; } diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index c4b9383..62d8b3f 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -1865,4 +1865,30 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L1865 {a: 1}.each(&->(k, v) {}) end end + + def test_any_hash_fixable + 20.times do + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + require "delegate" + typename = DelegateClass(String) + + hash = { + "Int" => true, + "Float" => true, + "String" => true, + "Boolean" => true, + "WidgetFilter" => true, + "WidgetAggregation" => true, + "WidgetEdge" => true, + "WidgetSortOrder" => true, + "WidgetGrouping" => true, + } + + hash.each_key do |key| + assert_send([hash, :key?, typename.new(key)]) + end + end; + end + end end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/