diff options
Diffstat (limited to 'actionpack/lib')
8 files changed, 74 insertions, 14 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 8e588812f8..603c2e9ea7 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -215,7 +215,7 @@ module AbstractController # ==== Returns # * <tt>string</tt> - The name of the method that handles the action # * false - No valid method name could be found. - # Raise AbstractController::ActionNotFound. + # Raise +AbstractController::ActionNotFound+. def _find_action_name(action_name) _valid_action_name?(action_name) && method_for_action(action_name) end @@ -231,11 +231,11 @@ module AbstractController # with a template matching the action name is considered to exist. # # If you override this method to handle additional cases, you may - # also provide a method (like _handle_method_missing) to handle + # also provide a method (like +_handle_method_missing+) to handle # the case. # - # If none of these conditions are true, and method_for_action - # returns nil, an AbstractController::ActionNotFound exception will be raised. + # If none of these conditions are true, and +method_for_action+ + # returns +nil+, an +AbstractController::ActionNotFound+ exception will be raised. # # ==== Parameters # * <tt>action_name</tt> - An action name to find a method name for diff --git a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb index 6c103bb042..798564db96 100644 --- a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb +++ b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb @@ -40,7 +40,7 @@ module ActionController end # Pick the template digest to include in the ETag. If the +:template+ option - # is present, use the named template. If +:template+ is nil or absent, use + # is present, use the named template. If +:template+ is +nil+ or absent, use # the default controller/action template. If +:template+ is false, omit the # template digest from the ETag. def pick_template_for_etag(options) diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 9c82abb640..e14da22e01 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -334,6 +334,15 @@ module ActionController # params = ActionController::Parameters.new(tags: ['rails', 'parameters']) # params.permit(tags: []) # + # Sometimes it is not possible or convenient to declare the valid keys of + # a hash parameter or its internal structure. Just map to an empty hash: + # + # params.permit(preferences: {}) + # + # but be careful because this opens the door to arbitrary input. In this + # case, +permit+ ensures values in the returned structure are permitted + # scalars and filters out anything else. + # # You can also use +permit+ on nested parameters, like: # # params = ActionController::Parameters.new({ @@ -382,14 +391,15 @@ module ActionController case filter when Symbol, String permitted_scalar_filter(params, filter) - when Hash then + when Hash hash_filter(params, filter) end end unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters - params.permit! + params.permitted = true + params end # Returns a parameter for the given +key+. If not found, @@ -539,7 +549,7 @@ module ActionController new_instance_with_inherited_permitted_status(@parameters.select(&block)) end - # Equivalent to Hash#keep_if, but returns nil if no changes were made. + # Equivalent to Hash#keep_if, but returns +nil+ if no changes were made. def select!(&block) @parameters.select!(&block) self @@ -573,6 +583,13 @@ module ActionController ) end + # Returns current <tt>ActionController::Parameters</tt> instance which + # +other_hash+ merges into current hash. + def merge!(other_hash) + @parameters.merge!(other_hash.to_h) + self + end + # This is required by ActiveModel attribute assignment, so that user can # pass +Parameters+ to a mass assignment methods in a model. It should not # matter as we are using +HashWithIndifferentAccess+ internally. @@ -759,6 +776,7 @@ module ActionController end EMPTY_ARRAY = [] + EMPTY_HASH = {} def hash_filter(params, filter) filter = filter.with_indifferent_access @@ -772,6 +790,11 @@ module ActionController array_of_permitted_scalars?(self[key]) do |val| params[key] = val end + elsif filter[key] == EMPTY_HASH + # Declaration { preferences: {} }. + if value.is_a?(Parameters) + params[key] = permit_any_in_parameters(value) + end elsif non_scalar?(value) # Declaration { user: :name } or { user: [:name, :age, { address: ... }] }. params[key] = each_element(value) do |element| @@ -781,6 +804,39 @@ module ActionController end end + def permit_any_in_parameters(params) + self.class.new.tap do |sanitized| + params.each do |key, value| + case value + when ->(v) { permitted_scalar?(v) } + sanitized[key] = value + when Array + sanitized[key] = permit_any_in_array(value) + when Parameters + sanitized[key] = permit_any_in_parameters(value) + else + # Filter this one out. + end + end + sanitized.permitted = true + end + end + + def permit_any_in_array(array) + [].tap do |sanitized| + array.each do |element| + case element + when ->(e) { permitted_scalar?(e) } + sanitized << element + when Parameters + sanitized << permit_any_in_parameters(element) + else + # Filter this one out. + end + end + end + end + def initialize_copy(source) super @parameters = @parameters.dup diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 803ac52605..357ca56036 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -249,7 +249,7 @@ module ActionDispatch # :nodoc: end end - # Sets the HTTP character set. In case of nil parameter + # Sets the HTTP character set. In case of +nil+ parameter # it sets the charset to utf-8. # # response.charset = 'utf-16' # => 'utf-16' diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 4fc4df4463..956c53e813 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -179,7 +179,7 @@ module ActionDispatch # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed - # cookie was tampered with by the user (or a 3rd party), nil will be returned. + # cookie was tampered with by the user (or a 3rd party), +nil+ will be returned. # # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. @@ -202,7 +202,7 @@ module ActionDispatch end # Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read. - # If the cookie was tampered with by the user (or a 3rd party), nil will be returned. + # If the cookie was tampered with by the user (or a 3rd party), +nil+ will be returned. # # If +secrets.secret_key_base+ and +secrets.secret_token+ (deprecated) are both set, # legacy cookies signed with the old key generator will be transparently upgraded. diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 1a9018fe0c..1c720c5a8e 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -175,7 +175,11 @@ module ActionDispatch end def log_array(logger, array) - array.map { |line| logger.fatal line } + if logger.formatter && logger.formatter.respond_to?(:tags_text) + logger.fatal array.join("\n#{logger.formatter.tags_text}") + else + logger.fatal array.join("\n") + end end def logger(request) diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 6900934712..6dddcc6ee1 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -129,7 +129,7 @@ module ActionDispatch end # Builds a hash containing the flashes to keep for the next request. - # If there are none to keep, returns nil. + # If there are none to keep, returns +nil+. def to_session_value #:nodoc: flashes_to_keep = @flashes.except(*@discard) return nil if flashes_to_keep.empty? diff --git a/actionpack/lib/action_dispatch/request/session.rb b/actionpack/lib/action_dispatch/request/session.rb index 8b98009efc..a2a80f39fc 100644 --- a/actionpack/lib/action_dispatch/request/session.rb +++ b/actionpack/lib/action_dispatch/request/session.rb @@ -85,7 +85,7 @@ module ActionDispatch end # Returns value of the key stored in the session or - # nil if the given key is not found in the session. + # +nil+ if the given key is not found in the session. def [](key) load_for_read! @delegate[key.to_s] |