mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Prevent side effects in Hash#with_indifferent_access
.
This commit is contained in:
parent
bf4f8211e1
commit
c44a929f49
3 changed files with 25 additions and 6 deletions
|
@ -1,3 +1,9 @@
|
|||
* Prevent side effects to hashes inside arrays when
|
||||
`Hash#with_indifferent_access` is called.
|
||||
Fixes #10526
|
||||
|
||||
*Yves Senn*
|
||||
|
||||
* Raise an error when multiple `included` blocks are defined for a Concern.
|
||||
The old behavior would silently discard previously defined blocks, running
|
||||
only the last one.
|
||||
|
|
|
@ -91,7 +91,7 @@ module ActiveSupport
|
|||
#
|
||||
# This value can be later fetched using either +:key+ or +'key'+.
|
||||
def []=(key, value)
|
||||
regular_writer(convert_key(key), convert_value(value))
|
||||
regular_writer(convert_key(key), convert_value(value, for: :assignment))
|
||||
end
|
||||
|
||||
alias_method :store, :[]=
|
||||
|
@ -231,7 +231,7 @@ module ActiveSupport
|
|||
def to_hash
|
||||
_new_hash= {}
|
||||
each do |key, value|
|
||||
_new_hash[convert_key(key)] = convert_value(value, true)
|
||||
_new_hash[convert_key(key)] = convert_value(value, for: :to_hash)
|
||||
end
|
||||
Hash.new(default).merge!(_new_hash)
|
||||
end
|
||||
|
@ -241,12 +241,18 @@ module ActiveSupport
|
|||
key.kind_of?(Symbol) ? key.to_s : key
|
||||
end
|
||||
|
||||
def convert_value(value, _convert_for_to_hash = false)
|
||||
def convert_value(value, options = {})
|
||||
if value.is_a? Hash
|
||||
_convert_for_to_hash ? value.to_hash : value.nested_under_indifferent_access
|
||||
if options[:for] == :to_hash
|
||||
value.to_hash
|
||||
else
|
||||
value.nested_under_indifferent_access
|
||||
end
|
||||
elsif value.is_a?(Array)
|
||||
value = value.dup if value.frozen?
|
||||
value.map! { |e| convert_value(e, _convert_for_to_hash) }
|
||||
unless options[:for] == :assignment
|
||||
value = value.dup
|
||||
end
|
||||
value.map! { |e| convert_value(e, options) }
|
||||
else
|
||||
value
|
||||
end
|
||||
|
|
|
@ -503,6 +503,13 @@ class HashExtTest < ActiveSupport::TestCase
|
|||
assert_equal [1], hash[:a]
|
||||
end
|
||||
|
||||
def test_with_indifferent_access_has_no_side_effects_on_existing_hash
|
||||
hash = {content: [{:foo => :bar, 'bar' => 'baz'}]}
|
||||
hash.with_indifferent_access
|
||||
|
||||
assert_equal [:foo, "bar"], hash[:content].first.keys
|
||||
end
|
||||
|
||||
def test_indifferent_hash_with_array_of_hashes
|
||||
hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access
|
||||
assert_equal "1", hash[:urls][:url].first[:address]
|
||||
|
|
Loading…
Reference in a new issue