提交 ba3dd5ca 编写于 作者: T Tim Rogers

Changes to a dupped `ActionController::Parameters` mutate the original

When `ActionController::Parameters` is duplicated with `#dup`, it doesn't create a duplicate of the instance variables (e.g. `@parameters`) but rather maintains the reference (see <http://ruby-doc.org/core-2.3.1/Object.html>). Given that the parameters object is often manipulated as if it were a hash (e.g. with `#delete` and similar methods), this leads to unexpected behaviour, like the following:

```
params = ActionController::Parameters.new(foo: "bar")
duplicated_params = params.dup
duplicated_params.delete(:foo)

params == duplicated_params
```

This fixes the bug by defining a private `#initialize_copy` method, used internally by `#dup`, which makes a copy of `@parameters`.
上级 6038a548
......@@ -783,6 +783,11 @@ def hash_filter(params, filter)
end
end
end
def initialize_copy(source)
super
@parameters = source.instance_variable_get(:@parameters).dup
end
end
# == Strong \Parameters
......
require 'abstract_unit'
require 'action_controller/metal/strong_parameters'
class ParametersDupTest < ActiveSupport::TestCase
setup do
ActionController::Parameters.permit_all_parameters = false
@params = ActionController::Parameters.new(
person: {
age: '32',
name: {
first: 'David',
last: 'Heinemeier Hansson'
},
addresses: [{city: 'Chicago', state: 'Illinois'}]
}
)
end
test "changes on a duplicate do not affect the original" do
dupped_params = @params.dup
dupped_params.delete(:person)
assert_not_equal @params, dupped_params
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册