diff options
Diffstat (limited to 'actionpack/lib/action_controller/metal/strong_parameters.rb')
| -rw-r--r-- | actionpack/lib/action_controller/metal/strong_parameters.rb | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 130ba61786..d3382ef296 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -1,8 +1,10 @@ require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/hash/transform_values' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/string/filters' require 'active_support/rescuable' require 'action_dispatch/http/upload' +require 'rack/test' require 'stringio' require 'set' @@ -107,7 +109,8 @@ module ActionController cattr_accessor :permit_all_parameters, instance_accessor: false cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false - delegate :keys, :key?, :has_key?, :empty?, :inspect, to: :@parameters + delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?, :inspect, + :as_json, to: :@parameters # By default, never raise an UnpermittedParameters exception if these # params are present. The default includes both 'controller' and 'action' @@ -157,12 +160,16 @@ module ActionController if other_hash.respond_to?(:permitted?) super else - @parameters == other_hash + if other_hash.is_a?(Hash) + @parameters == other_hash.with_indifferent_access + else + @parameters == other_hash + end end end - # Returns a safe +Hash+ representation of this parameter with all - # unpermitted keys removed. + # Returns a safe <tt>ActiveSupport::HashWithIndifferentAccess</tt> + # representation of this parameter with all unpermitted keys removed. # # params = ActionController::Parameters.new({ # name: 'Senjougahara Hitagi', @@ -174,15 +181,17 @@ module ActionController # safe_params.to_h # => {"name"=>"Senjougahara Hitagi"} def to_h if permitted? - @parameters.to_h + convert_parameters_to_hashes(@parameters, :to_h) else slice(*self.class.always_permitted_parameters).permit!.to_h end end - # Returns an unsafe, unfiltered +Hash+ representation of this parameter. + # Returns an unsafe, unfiltered + # <tt>ActiveSupport::HashWithIndifferentAccess</tt> representation of this + # parameter. def to_unsafe_h - @parameters.to_h + convert_parameters_to_hashes(@parameters, :to_unsafe_h) end alias_method :to_unsafe_hash, :to_unsafe_h @@ -415,7 +424,7 @@ module ActionController # params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none # params.fetch(:none, 'Francesco') # => "Francesco" # params.fetch(:none) { 'Francesco' } # => "Francesco" - def fetch(key, *args, &block) + def fetch(key, *args) convert_value_to_parameters( @parameters.fetch(key) { if block_given? @@ -510,7 +519,7 @@ module ActionController # to key. If the key is not found, returns the default value. If the # optional code block is given and the key is not found, pass in the key # and return the result of block. - def delete(key, &block) + def delete(key) convert_value_to_parameters(@parameters.delete(key)) end @@ -575,6 +584,24 @@ module ActionController dup end + def method_missing(method_sym, *args, &block) + if @parameters.respond_to?(method_sym) + message = <<-DEPRECATE.squish + Method #{method_sym} is deprecated and will be removed in Rails 5.1, + as `ActionController::Parameters` no longer inherits from + hash. Using this deprecated behavior exposes potential security + problems. If you continue to use this method you may be creating + a security vulnerability in your app that can be exploited. Instead, + consider using one of these documented methods which are not + deprecated: http://api.rubyonrails.org/v#{ActionPack.version}/classes/ActionController/Parameters.html + DEPRECATE + ActiveSupport::Deprecation.warn(message) + @parameters.public_send(method_sym, *args, &block) + else + super + end + end + protected def permitted=(new_permitted) @permitted = new_permitted @@ -591,6 +618,21 @@ module ActionController end end + def convert_parameters_to_hashes(value, using) + case value + when Array + value.map { |v| convert_parameters_to_hashes(v, using) } + when Hash + value.transform_values do |v| + convert_parameters_to_hashes(v, using) + end.with_indifferent_access + when Parameters + value.send(using) + else + value + end + end + def convert_hashes_to_parameters(key, value) converted = convert_value_to_parameters(value) @parameters[key] = converted unless converted.equal?(value) |
