actionpack 5.2.4.4 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -322
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/abstract_controller.rb +1 -0
  6. data/lib/abstract_controller/base.rb +38 -4
  7. data/lib/abstract_controller/caching.rb +1 -1
  8. data/lib/abstract_controller/caching/fragments.rb +6 -22
  9. data/lib/abstract_controller/callbacks.rb +14 -2
  10. data/lib/abstract_controller/collector.rb +1 -2
  11. data/lib/abstract_controller/helpers.rb +106 -90
  12. data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
  13. data/lib/abstract_controller/rendering.rb +9 -9
  14. data/lib/abstract_controller/translation.rb +11 -5
  15. data/lib/action_controller.rb +7 -4
  16. data/lib/action_controller/api.rb +4 -3
  17. data/lib/action_controller/base.rb +6 -9
  18. data/lib/action_controller/caching.rb +1 -3
  19. data/lib/action_controller/log_subscriber.rb +10 -7
  20. data/lib/action_controller/metal.rb +10 -8
  21. data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
  22. data/lib/action_controller/metal/conditional_get.rb +19 -5
  23. data/lib/action_controller/metal/content_security_policy.rb +1 -2
  24. data/lib/action_controller/metal/cookies.rb +3 -1
  25. data/lib/action_controller/metal/data_streaming.rb +6 -7
  26. data/lib/action_controller/metal/default_headers.rb +17 -0
  27. data/lib/action_controller/metal/etag_with_template_digest.rb +3 -5
  28. data/lib/action_controller/metal/exceptions.rb +56 -2
  29. data/lib/action_controller/metal/flash.rb +5 -5
  30. data/lib/action_controller/metal/head.rb +7 -4
  31. data/lib/action_controller/metal/helpers.rb +14 -5
  32. data/lib/action_controller/metal/http_authentication.rb +24 -23
  33. data/lib/action_controller/metal/implicit_render.rb +5 -15
  34. data/lib/action_controller/metal/instrumentation.rb +13 -14
  35. data/lib/action_controller/metal/live.rb +30 -32
  36. data/lib/action_controller/metal/logging.rb +20 -0
  37. data/lib/action_controller/metal/mime_responds.rb +19 -4
  38. data/lib/action_controller/metal/parameter_encoding.rb +35 -4
  39. data/lib/action_controller/metal/params_wrapper.rb +31 -22
  40. data/lib/action_controller/metal/permissions_policy.rb +46 -0
  41. data/lib/action_controller/metal/redirecting.rb +6 -6
  42. data/lib/action_controller/metal/renderers.rb +4 -4
  43. data/lib/action_controller/metal/rendering.rb +8 -3
  44. data/lib/action_controller/metal/request_forgery_protection.rb +62 -34
  45. data/lib/action_controller/metal/rescue.rb +1 -1
  46. data/lib/action_controller/metal/streaming.rb +0 -1
  47. data/lib/action_controller/metal/strong_parameters.rb +167 -58
  48. data/lib/action_controller/metal/url_for.rb +1 -1
  49. data/lib/action_controller/railties/helpers.rb +1 -1
  50. data/lib/action_controller/renderer.rb +37 -13
  51. data/lib/action_controller/template_assertions.rb +1 -1
  52. data/lib/action_controller/test_case.rb +70 -65
  53. data/lib/action_dispatch.rb +9 -3
  54. data/lib/action_dispatch/http/cache.rb +26 -21
  55. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  56. data/lib/action_dispatch/http/content_security_policy.rb +33 -19
  57. data/lib/action_dispatch/http/filter_parameters.rb +9 -8
  58. data/lib/action_dispatch/http/filter_redirect.rb +2 -3
  59. data/lib/action_dispatch/http/headers.rb +4 -4
  60. data/lib/action_dispatch/http/mime_negotiation.rb +26 -13
  61. data/lib/action_dispatch/http/mime_type.rb +42 -23
  62. data/lib/action_dispatch/http/parameters.rb +14 -23
  63. data/lib/action_dispatch/http/permissions_policy.rb +173 -0
  64. data/lib/action_dispatch/http/request.rb +45 -22
  65. data/lib/action_dispatch/http/response.rb +45 -25
  66. data/lib/action_dispatch/http/upload.rb +9 -1
  67. data/lib/action_dispatch/http/url.rb +82 -82
  68. data/lib/action_dispatch/journey.rb +0 -2
  69. data/lib/action_dispatch/journey/formatter.rb +54 -30
  70. data/lib/action_dispatch/journey/gtg/builder.rb +22 -37
  71. data/lib/action_dispatch/journey/gtg/simulator.rb +8 -7
  72. data/lib/action_dispatch/journey/gtg/transition_table.rb +6 -5
  73. data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
  74. data/lib/action_dispatch/journey/nodes/node.rb +13 -11
  75. data/lib/action_dispatch/journey/parser.rb +13 -13
  76. data/lib/action_dispatch/journey/parser.y +1 -1
  77. data/lib/action_dispatch/journey/path/pattern.rb +19 -21
  78. data/lib/action_dispatch/journey/route.rb +10 -20
  79. data/lib/action_dispatch/journey/router.rb +26 -34
  80. data/lib/action_dispatch/journey/router/utils.rb +14 -12
  81. data/lib/action_dispatch/journey/routes.rb +0 -2
  82. data/lib/action_dispatch/journey/scanner.rb +10 -4
  83. data/lib/action_dispatch/journey/visitors.rb +1 -4
  84. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  85. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  86. data/lib/action_dispatch/middleware/cookies.rb +128 -109
  87. data/lib/action_dispatch/middleware/debug_exceptions.rb +43 -66
  88. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  89. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  90. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -30
  91. data/lib/action_dispatch/middleware/flash.rb +1 -1
  92. data/lib/action_dispatch/middleware/host_authorization.rb +121 -0
  93. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -3
  94. data/lib/action_dispatch/middleware/remote_ip.rb +14 -16
  95. data/lib/action_dispatch/middleware/request_id.rb +5 -6
  96. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -3
  97. data/lib/action_dispatch/middleware/session/cookie_store.rb +3 -9
  98. data/lib/action_dispatch/middleware/show_exceptions.rb +3 -2
  99. data/lib/action_dispatch/middleware/ssl.rb +20 -15
  100. data/lib/action_dispatch/middleware/stack.rb +56 -2
  101. data/lib/action_dispatch/middleware/static.rb +153 -93
  102. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  103. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
  106. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  107. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  108. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  109. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +23 -4
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  113. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +6 -3
  114. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -1
  115. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +104 -8
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  119. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
  122. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +24 -1
  123. data/lib/action_dispatch/railtie.rb +8 -2
  124. data/lib/action_dispatch/request/session.rb +10 -9
  125. data/lib/action_dispatch/request/utils.rb +26 -2
  126. data/lib/action_dispatch/routing.rb +21 -20
  127. data/lib/action_dispatch/routing/inspector.rb +100 -52
  128. data/lib/action_dispatch/routing/mapper.rb +155 -103
  129. data/lib/action_dispatch/routing/polymorphic_routes.rb +13 -15
  130. data/lib/action_dispatch/routing/redirection.rb +3 -3
  131. data/lib/action_dispatch/routing/route_set.rb +71 -69
  132. data/lib/action_dispatch/routing/url_for.rb +2 -2
  133. data/lib/action_dispatch/system_test_case.rb +54 -11
  134. data/lib/action_dispatch/system_testing/browser.rb +53 -16
  135. data/lib/action_dispatch/system_testing/driver.rb +11 -3
  136. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +49 -7
  137. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +8 -10
  138. data/lib/action_dispatch/testing/assertion_response.rb +0 -1
  139. data/lib/action_dispatch/testing/assertions.rb +1 -1
  140. data/lib/action_dispatch/testing/assertions/response.rb +4 -7
  141. data/lib/action_dispatch/testing/assertions/routing.rb +20 -8
  142. data/lib/action_dispatch/testing/integration.rb +61 -28
  143. data/lib/action_dispatch/testing/request_encoder.rb +2 -2
  144. data/lib/action_dispatch/testing/test_process.rb +29 -4
  145. data/lib/action_dispatch/testing/test_request.rb +3 -3
  146. data/lib/action_dispatch/testing/test_response.rb +4 -32
  147. data/lib/action_pack.rb +1 -1
  148. data/lib/action_pack/gem_version.rb +4 -4
  149. metadata +38 -26
  150. data/lib/action_controller/metal/force_ssl.rb +0 -99
  151. data/lib/action_dispatch/http/parameter_filter.rb +0 -86
  152. data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
  153. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -49
  154. data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -120
  155. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -18,7 +18,7 @@ module ActionController #:nodoc:
18
18
  end
19
19
 
20
20
  private
21
- def process_action(*args)
21
+ def process_action(*)
22
22
  super
23
23
  rescue Exception => exception
24
24
  request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
@@ -196,7 +196,6 @@ module ActionController #:nodoc:
196
196
  extend ActiveSupport::Concern
197
197
 
198
198
  private
199
-
200
199
  # Set proper cache control and transfer encoding when streaming
201
200
  def _process_options(options)
202
201
  super
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/hash/indifferent_access"
4
- require "active_support/core_ext/hash/transform_values"
5
4
  require "active_support/core_ext/array/wrap"
6
5
  require "active_support/core_ext/string/filters"
7
6
  require "active_support/core_ext/object/to_query"
8
- require "active_support/rescuable"
9
7
  require "action_dispatch/http/upload"
10
8
  require "rack/test"
11
9
  require "stringio"
@@ -21,12 +19,36 @@ module ActionController
21
19
  # params.require(:a)
22
20
  # # => ActionController::ParameterMissing: param is missing or the value is empty: a
23
21
  class ParameterMissing < KeyError
24
- attr_reader :param # :nodoc:
22
+ attr_reader :param, :keys # :nodoc:
25
23
 
26
- def initialize(param) # :nodoc:
24
+ def initialize(param, keys = nil) # :nodoc:
27
25
  @param = param
26
+ @keys = keys
28
27
  super("param is missing or the value is empty: #{param}")
29
28
  end
29
+
30
+ class Correction
31
+ def initialize(error)
32
+ @error = error
33
+ end
34
+
35
+ def corrections
36
+ if @error.param && @error.keys
37
+ maybe_these = @error.keys
38
+
39
+ maybe_these.sort_by { |n|
40
+ DidYouMean::Jaro.distance(@error.param.to_s, n)
41
+ }.reverse.first(4)
42
+ else
43
+ []
44
+ end
45
+ end
46
+ end
47
+
48
+ # We may not have DYM, and DYM might not let us register error handlers
49
+ if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
50
+ DidYouMean.correct_error(self, Correction)
51
+ end
30
52
  end
31
53
 
32
54
  # Raised when a supplied parameter is not expected and
@@ -59,7 +81,7 @@ module ActionController
59
81
 
60
82
  # == Action Controller \Parameters
61
83
  #
62
- # Allows you to choose which attributes should be whitelisted for mass updating
84
+ # Allows you to choose which attributes should be permitted for mass updating
63
85
  # and thus prevent accidentally exposing that which shouldn't be exposed.
64
86
  # Provides two methods for this purpose: #require and #permit. The former is
65
87
  # used to mark parameters as required. The latter is used to set the parameter
@@ -133,6 +155,15 @@ module ActionController
133
155
  #
134
156
  # Returns a hash that can be used as the JSON representation for the parameters.
135
157
 
158
+ ##
159
+ # :method: each_key
160
+ #
161
+ # :call-seq:
162
+ # each_key()
163
+ #
164
+ # Calls block once for each key in the parameters, passing the key.
165
+ # If no block is given, an enumerator is returned instead.
166
+
136
167
  ##
137
168
  # :method: empty?
138
169
  #
@@ -173,6 +204,14 @@ module ActionController
173
204
  #
174
205
  # Returns true if the given key is present in the parameters.
175
206
 
207
+ ##
208
+ # :method: member?
209
+ #
210
+ # :call-seq:
211
+ # member?(key)
212
+ #
213
+ # Returns true if the given key is present in the parameters.
214
+
176
215
  ##
177
216
  # :method: keys
178
217
  #
@@ -204,8 +243,8 @@ module ActionController
204
243
  # values()
205
244
  #
206
245
  # Returns a new array of the values of the parameters.
207
- delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
208
- :as_json, :to_s, to: :@parameters
246
+ delegate :keys, :key?, :has_key?, :member?, :values, :has_value?, :value?, :empty?, :include?,
247
+ :as_json, :to_s, :each_key, to: :@parameters
209
248
 
210
249
  # By default, never raise an UnpermittedParameters exception if these
211
250
  # params are present. The default includes both 'controller' and 'action'
@@ -213,9 +252,15 @@ module ActionController
213
252
  # to change these is to specify `always_permitted_parameters` in your
214
253
  # config. For instance:
215
254
  #
216
- # config.always_permitted_parameters = %w( controller action format )
255
+ # config.action_controller.always_permitted_parameters = %w( controller action format )
217
256
  cattr_accessor :always_permitted_parameters, default: %w( controller action )
218
257
 
258
+ class << self
259
+ def nested_attribute?(key, value) # :nodoc:
260
+ /\A-?\d+\z/.match?(key) && (value.is_a?(Hash) || value.is_a?(Parameters))
261
+ end
262
+ end
263
+
219
264
  # Returns a new instance of <tt>ActionController::Parameters</tt>.
220
265
  # Also, sets the +permitted+ attribute to the default value of
221
266
  # <tt>ActionController::Parameters.permit_all_parameters</tt>.
@@ -246,6 +291,11 @@ module ActionController
246
291
  @parameters == other
247
292
  end
248
293
  end
294
+ alias eql? ==
295
+
296
+ def hash
297
+ [@parameters.hash, @permitted].hash
298
+ end
249
299
 
250
300
  # Returns a safe <tt>ActiveSupport::HashWithIndifferentAccess</tt>
251
301
  # representation of the parameters with all unpermitted keys removed.
@@ -334,6 +384,7 @@ module ActionController
334
384
  # Convert all hashes in values into parameters, then yield each pair in
335
385
  # the same way as <tt>Hash#each_pair</tt>.
336
386
  def each_pair(&block)
387
+ return to_enum(__callee__) unless block_given?
337
388
  @parameters.each_pair do |key, value|
338
389
  yield [key, convert_hashes_to_parameters(key, value)]
339
390
  end
@@ -342,6 +393,17 @@ module ActionController
342
393
  end
343
394
  alias_method :each, :each_pair
344
395
 
396
+ # Convert all hashes in values into parameters, then yield each value in
397
+ # the same way as <tt>Hash#each_value</tt>.
398
+ def each_value(&block)
399
+ return to_enum(:each_value) unless block_given?
400
+ @parameters.each_pair do |key, value|
401
+ yield convert_hashes_to_parameters(key, value)
402
+ end
403
+
404
+ self
405
+ end
406
+
345
407
  # Attribute that keeps track of converted arrays, if any, to avoid double
346
408
  # looping in the common use case permit + mass-assignment. Defined in a
347
409
  # method to instantiate it only if needed.
@@ -442,7 +504,7 @@ module ActionController
442
504
  if value.present? || value == false
443
505
  value
444
506
  else
445
- raise ParameterMissing.new(key)
507
+ raise ParameterMissing.new(key, @parameters.keys)
446
508
  end
447
509
  end
448
510
 
@@ -508,7 +570,7 @@ module ActionController
508
570
  #
509
571
  # Note that if you use +permit+ in a key that points to a hash,
510
572
  # it won't allow all the hash. You also need to specify which
511
- # attributes inside the hash should be whitelisted.
573
+ # attributes inside the hash should be permitted.
512
574
  #
513
575
  # params = ActionController::Parameters.new({
514
576
  # person: {
@@ -579,26 +641,24 @@ module ActionController
579
641
  if block_given?
580
642
  yield
581
643
  else
582
- args.fetch(0) { raise ActionController::ParameterMissing.new(key) }
644
+ args.fetch(0) { raise ActionController::ParameterMissing.new(key, @parameters.keys) }
583
645
  end
584
646
  }
585
647
  )
586
648
  end
587
649
 
588
- if Hash.method_defined?(:dig)
589
- # Extracts the nested parameter from the given +keys+ by calling +dig+
590
- # at each step. Returns +nil+ if any intermediate step is +nil+.
591
- #
592
- # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
593
- # params.dig(:foo, :bar, :baz) # => 1
594
- # params.dig(:foo, :zot, :xyz) # => nil
595
- #
596
- # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
597
- # params2.dig(:foo, 1) # => 11
598
- def dig(*keys)
599
- convert_hashes_to_parameters(keys.first, @parameters[keys.first])
600
- @parameters.dig(*keys)
601
- end
650
+ # Extracts the nested parameter from the given +keys+ by calling +dig+
651
+ # at each step. Returns +nil+ if any intermediate step is +nil+.
652
+ #
653
+ # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
654
+ # params.dig(:foo, :bar, :baz) # => 1
655
+ # params.dig(:foo, :zot, :xyz) # => nil
656
+ #
657
+ # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
658
+ # params2.dig(:foo, 1) # => 11
659
+ def dig(*keys)
660
+ convert_hashes_to_parameters(keys.first, @parameters[keys.first])
661
+ @parameters.dig(*keys)
602
662
  end
603
663
 
604
664
  # Returns a new <tt>ActionController::Parameters</tt> instance that
@@ -662,22 +722,37 @@ module ActionController
662
722
  # Returns a new <tt>ActionController::Parameters</tt> instance with the
663
723
  # results of running +block+ once for every key. The values are unchanged.
664
724
  def transform_keys(&block)
665
- if block
666
- new_instance_with_inherited_permitted_status(
667
- @parameters.transform_keys(&block)
668
- )
669
- else
670
- @parameters.transform_keys
671
- end
725
+ return to_enum(:transform_keys) unless block_given?
726
+ new_instance_with_inherited_permitted_status(
727
+ @parameters.transform_keys(&block)
728
+ )
672
729
  end
673
730
 
674
731
  # Performs keys transformation and returns the altered
675
732
  # <tt>ActionController::Parameters</tt> instance.
676
733
  def transform_keys!(&block)
734
+ return to_enum(:transform_keys!) unless block_given?
677
735
  @parameters.transform_keys!(&block)
678
736
  self
679
737
  end
680
738
 
739
+ # Returns a new <tt>ActionController::Parameters</tt> instance with the
740
+ # results of running +block+ once for every key. This includes the keys
741
+ # from the root hash and from all nested hashes and arrays. The values are unchanged.
742
+ def deep_transform_keys(&block)
743
+ new_instance_with_inherited_permitted_status(
744
+ @parameters.deep_transform_keys(&block)
745
+ )
746
+ end
747
+
748
+ # Returns the <tt>ActionController::Parameters</tt> instance changing its keys.
749
+ # This includes the keys from the root hash and from all nested hashes and arrays.
750
+ # The values are unchanged.
751
+ def deep_transform_keys!(&block)
752
+ @parameters.deep_transform_keys!(&block)
753
+ self
754
+ end
755
+
681
756
  # Deletes a key-value pair from +Parameters+ and returns the value. If
682
757
  # +key+ is not found, returns +nil+ (or, with optional code block, yields
683
758
  # +key+ and returns the result). Cf. +#extract!+, which returns the
@@ -712,6 +787,28 @@ module ActionController
712
787
  end
713
788
  alias_method :delete_if, :reject!
714
789
 
790
+ # Returns a new instance of <tt>ActionController::Parameters</tt> with +nil+ values removed.
791
+ def compact
792
+ new_instance_with_inherited_permitted_status(@parameters.compact)
793
+ end
794
+
795
+ # Removes all +nil+ values in place and returns +self+, or +nil+ if no changes were made.
796
+ def compact!
797
+ self if @parameters.compact!
798
+ end
799
+
800
+ # Returns a new instance of <tt>ActionController::Parameters</tt> without the blank values.
801
+ # Uses Object#blank? for determining if a value is blank.
802
+ def compact_blank
803
+ reject { |_k, v| v.blank? }
804
+ end
805
+
806
+ # Removes all blank values in place and returns self.
807
+ # Uses Object#blank? for determining if a value is blank.
808
+ def compact_blank!
809
+ reject! { |_k, v| v.blank? }
810
+ end
811
+
715
812
  # Returns values that were assigned to the given +keys+. Note that all the
716
813
  # +Hash+ objects will be converted to <tt>ActionController::Parameters</tt>.
717
814
  def values_at(*keys)
@@ -758,7 +855,7 @@ module ActionController
758
855
  end
759
856
 
760
857
  def inspect
761
- "<#{self.class} #{@parameters} permitted: #{@permitted}>"
858
+ "#<#{self.class} #{@parameters} permitted: #{@permitted}>"
762
859
  end
763
860
 
764
861
  def self.hook_into_yaml_loading # :nodoc:
@@ -783,7 +880,7 @@ module ActionController
783
880
  @permitted = coder.map["ivars"][:@permitted]
784
881
  when "!ruby/object:ActionController::Parameters"
785
882
  # YAML's Object format. Only needed because of the format
786
- # backwardscompability above, otherwise equivalent to YAML's initialization.
883
+ # backwards compatibility above, otherwise equivalent to YAML's initialization.
787
884
  @parameters, @permitted = coder.map["parameters"], coder.map["permitted"]
788
885
  end
789
886
  end
@@ -798,12 +895,16 @@ module ActionController
798
895
  protected
799
896
  attr_reader :parameters
800
897
 
801
- def permitted=(new_permitted)
802
- @permitted = new_permitted
898
+ attr_writer :permitted
899
+
900
+ def nested_attributes?
901
+ @parameters.any? { |k, v| Parameters.nested_attribute?(k, v) }
803
902
  end
804
903
 
805
- def fields_for_style?
806
- @parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
904
+ def each_nested_attribute
905
+ hash = self.class.new
906
+ self.each { |k, v| hash[k] = yield v if Parameters.nested_attribute?(k, v) }
907
+ hash
807
908
  end
808
909
 
809
910
  private
@@ -848,15 +949,13 @@ module ActionController
848
949
  end
849
950
  end
850
951
 
851
- def each_element(object)
952
+ def each_element(object, &block)
852
953
  case object
853
954
  when Array
854
955
  object.grep(Parameters).map { |el| yield el }.compact
855
956
  when Parameters
856
- if object.fields_for_style?
857
- hash = object.class.new
858
- object.each { |k, v| hash[k] = yield v }
859
- hash
957
+ if object.nested_attributes?
958
+ object.each_nested_attribute(&block)
860
959
  else
861
960
  yield object
862
961
  end
@@ -884,7 +983,7 @@ module ActionController
884
983
  # --- Filtering ----------------------------------------------------------
885
984
  #
886
985
 
887
- # This is a white list of permitted scalar types that includes the ones
986
+ # This is a list of permitted scalar types that includes the ones
888
987
  # supported in XML and JSON requests.
889
988
  #
890
989
  # This list is in particular used to filter ordinary requests, String goes
@@ -911,15 +1010,28 @@ module ActionController
911
1010
  PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) }
912
1011
  end
913
1012
 
914
- def permitted_scalar_filter(params, key)
915
- if has_key?(key) && permitted_scalar?(self[key])
916
- params[key] = self[key]
1013
+ # Adds existing keys to the params if their values are scalar.
1014
+ #
1015
+ # For example:
1016
+ #
1017
+ # puts self.keys #=> ["zipcode(90210i)"]
1018
+ # params = {}
1019
+ #
1020
+ # permitted_scalar_filter(params, "zipcode")
1021
+ #
1022
+ # puts params.keys # => ["zipcode"]
1023
+ def permitted_scalar_filter(params, permitted_key)
1024
+ permitted_key = permitted_key.to_s
1025
+
1026
+ if has_key?(permitted_key) && permitted_scalar?(self[permitted_key])
1027
+ params[permitted_key] = self[permitted_key]
917
1028
  end
918
1029
 
919
- keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k|
920
- if permitted_scalar?(self[k])
921
- params[k] = self[k]
922
- end
1030
+ each_key do |key|
1031
+ next unless key =~ /\(\d+[if]?\)\z/
1032
+ next unless $~.pre_match == permitted_key
1033
+
1034
+ params[key] = self[key] if permitted_scalar?(self[key])
923
1035
  end
924
1036
  end
925
1037
 
@@ -1004,8 +1116,8 @@ module ActionController
1004
1116
  #
1005
1117
  # It provides an interface for protecting attributes from end-user
1006
1118
  # assignment. This makes Action Controller parameters forbidden
1007
- # to be used in Active Model mass assignment until they have been
1008
- # whitelisted.
1119
+ # to be used in Active Model mass assignment until they have been explicitly
1120
+ # enumerated.
1009
1121
  #
1010
1122
  # In addition, parameters can be marked as required and flow through a
1011
1123
  # predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no
@@ -1041,7 +1153,7 @@ module ActionController
1041
1153
  # end
1042
1154
  #
1043
1155
  # In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
1044
- # will need to specify which nested attributes should be whitelisted. You might want
1156
+ # will need to specify which nested attributes should be permitted. You might want
1045
1157
  # to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information.
1046
1158
  #
1047
1159
  # class Person
@@ -1059,7 +1171,7 @@ module ActionController
1059
1171
  # private
1060
1172
  #
1061
1173
  # def person_params
1062
- # # It's mandatory to specify the nested attributes that should be whitelisted.
1174
+ # # It's mandatory to specify the nested attributes that should be permitted.
1063
1175
  # # If you use `permit` with just the key that points to the nested attributes hash,
1064
1176
  # # it will return an empty hash.
1065
1177
  # params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
@@ -1069,9 +1181,6 @@ module ActionController
1069
1181
  # See ActionController::Parameters.require and ActionController::Parameters.permit
1070
1182
  # for more information.
1071
1183
  module StrongParameters
1072
- extend ActiveSupport::Concern
1073
- include ActiveSupport::Rescuable
1074
-
1075
1184
  # Returns a new ActionController::Parameters object that
1076
1185
  # has been instantiated with the <tt>request.parameters</tt>.
1077
1186
  def params
@@ -44,7 +44,7 @@ module ActionController
44
44
  options[:original_script_name] = original_script_name
45
45
  else
46
46
  if same_origin
47
- options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
47
+ options[:script_name] = request.script_name.empty? ? "" : request.script_name.dup
48
48
  else
49
49
  options[:script_name] = script_name
50
50
  end
@@ -7,7 +7,7 @@ module ActionController
7
7
  super
8
8
  return unless klass.respond_to?(:helpers_path=)
9
9
 
10
- if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
10
+ if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
11
11
  paths = namespace.railtie_helpers_paths
12
12
  else
13
13
  paths = ActionController::Helpers.helpers_path