mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 09:33:59 +02:00
merge revision(s) f36a71e269
: [Backport #20307]
[Bug #20307] Fix `Hash#update` to make frozen copy of string keys
This commit is contained in:
parent
d802b6122b
commit
90a44bcd39
3 changed files with 18 additions and 15 deletions
14
hash.c
14
hash.c
|
@ -3968,19 +3968,10 @@ rb_hash_invert(VALUE hash)
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
|
|
||||||
{
|
|
||||||
*value = arg->arg;
|
|
||||||
return ST_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
|
rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
|
||||||
{
|
{
|
||||||
RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
|
rb_hash_aset(hash, key, value);
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3992,6 +3983,9 @@ rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_ar
|
||||||
if (existing) {
|
if (existing) {
|
||||||
newvalue = (st_data_t)rb_yield_values(3, (VALUE)*key, (VALUE)*value, (VALUE)newvalue);
|
newvalue = (st_data_t)rb_yield_values(3, (VALUE)*key, (VALUE)*value, (VALUE)newvalue);
|
||||||
}
|
}
|
||||||
|
else if (RHASH_STRING_KEY_P(arg->hash, *key) && !RB_OBJ_FROZEN(*key)) {
|
||||||
|
*key = rb_hash_key_str(*key);
|
||||||
|
}
|
||||||
*value = newvalue;
|
*value = newvalue;
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1397,6 +1397,15 @@ class TestHash < Test::Unit::TestCase
|
||||||
assert_equal(@cls[a: 10, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], h)
|
assert_equal(@cls[a: 10, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], h)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_on_identhash
|
||||||
|
key = +'a'
|
||||||
|
i = @cls[].compare_by_identity
|
||||||
|
i[key] = 0
|
||||||
|
h = @cls[].update(i)
|
||||||
|
key.upcase!
|
||||||
|
assert_equal(0, h.fetch('a'))
|
||||||
|
end
|
||||||
|
|
||||||
def test_merge
|
def test_merge
|
||||||
h1 = @cls[1=>2, 3=>4]
|
h1 = @cls[1=>2, 3=>4]
|
||||||
h2 = {1=>3, 5=>7}
|
h2 = {1=>3, 5=>7}
|
||||||
|
@ -1419,10 +1428,10 @@ class TestHash < Test::Unit::TestCase
|
||||||
expected[7] = 8
|
expected[7] = 8
|
||||||
h2 = h.merge(7=>8)
|
h2 = h.merge(7=>8)
|
||||||
assert_equal(expected, h2)
|
assert_equal(expected, h2)
|
||||||
assert_equal(true, h2.compare_by_identity?)
|
assert_predicate(h2, :compare_by_identity?)
|
||||||
h2 = h.merge({})
|
h2 = h.merge({})
|
||||||
assert_equal(h, h2)
|
assert_equal(h, h2)
|
||||||
assert_equal(true, h2.compare_by_identity?)
|
assert_predicate(h2, :compare_by_identity?)
|
||||||
|
|
||||||
h = @cls[]
|
h = @cls[]
|
||||||
h.compare_by_identity
|
h.compare_by_identity
|
||||||
|
@ -1430,10 +1439,10 @@ class TestHash < Test::Unit::TestCase
|
||||||
h1.compare_by_identity
|
h1.compare_by_identity
|
||||||
h2 = h.merge(7=>8)
|
h2 = h.merge(7=>8)
|
||||||
assert_equal(h1, h2)
|
assert_equal(h1, h2)
|
||||||
assert_equal(true, h2.compare_by_identity?)
|
assert_predicate(h2, :compare_by_identity?)
|
||||||
h2 = h.merge({})
|
h2 = h.merge({})
|
||||||
assert_equal(h, h2)
|
assert_equal(h, h2)
|
||||||
assert_equal(true, h2.compare_by_identity?)
|
assert_predicate(h2, :compare_by_identity?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_merge!
|
def test_merge!
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||||
#define RUBY_VERSION_TEENY 4
|
#define RUBY_VERSION_TEENY 4
|
||||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||||
#define RUBY_PATCHLEVEL 186
|
#define RUBY_PATCHLEVEL 187
|
||||||
|
|
||||||
#include "ruby/version.h"
|
#include "ruby/version.h"
|
||||||
#include "ruby/internal/abi.h"
|
#include "ruby/internal/abi.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue