mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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@neocat.jp>
This commit is contained in:
parent
b2030d4dae
commit
20a8425aa0
2 changed files with 29 additions and 8 deletions
11
hash.c
11
hash.c
|
@ -223,15 +223,10 @@ any_hash(VALUE a, st_index_t (*other_func)(VALUE))
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1865,4 +1865,30 @@ class TestHash < Test::Unit::TestCase
|
|||
{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
|
||||
|
|
Loading…
Reference in a new issue