diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 0f5afc0416..c544ec96cf 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,8 @@ +* Expose ActionController::Parameters#each_key which allows iterating over + keys without allocating an array. + + *Richard Schneeman* + * Purpose metadata for signed/encrypted cookies. Rails can now thwart attacks that attempt to copy signed/encrypted value diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 21859e5356..a37f08d944 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -132,6 +132,15 @@ module ActionController # # Returns a hash that can be used as the JSON representation for the parameters. + ## + # :method: each_key + # + # :call-seq: + # each_key() + # + # Calls block once for each key in the parameters, passing the key. + # If no block is given, an enumerator is returned instead. + ## # :method: empty? # @@ -204,7 +213,7 @@ module ActionController # # Returns a new array of the values of the parameters. delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?, - :as_json, :to_s, to: :@parameters + :as_json, :to_s, :each_key, to: :@parameters # By default, never raise an UnpermittedParameters exception if these # params are present. The default includes both 'controller' and 'action' @@ -914,15 +923,18 @@ module ActionController # permitted_scalar_filter(params, "zipcode") # # puts params.keys # => ["zipcode"] - def permitted_scalar_filter(params, key) - if has_key?(key) && permitted_scalar?(self[key]) - params[key] = self[key] + def permitted_scalar_filter(params, permitted_key) + permitted_key = permitted_key.to_s + + if has_key?(permitted_key) && permitted_scalar?(self[permitted_key]) + params[permitted_key] = self[permitted_key] end - keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k| - if permitted_scalar?(self[k]) - params[k] = self[k] - end + each_key do |key| + next unless key =~ /\(\d+[if]?\)\z/ + next unless $~.pre_match == permitted_key + + params[key] = self[key] if permitted_scalar?(self[key]) end end