[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]