actionpack 5.2.3 → 6.0.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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +191 -292
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -2
  5. data/lib/abstract_controller/base.rb +4 -2
  6. data/lib/abstract_controller/caching/fragments.rb +6 -22
  7. data/lib/abstract_controller/callbacks.rb +12 -0
  8. data/lib/abstract_controller/collector.rb +1 -1
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
  11. data/lib/abstract_controller/translation.rb +1 -0
  12. data/lib/action_controller.rb +5 -1
  13. data/lib/action_controller/api.rb +2 -1
  14. data/lib/action_controller/base.rb +2 -7
  15. data/lib/action_controller/caching.rb +1 -1
  16. data/lib/action_controller/log_subscriber.rb +8 -5
  17. data/lib/action_controller/metal.rb +3 -3
  18. data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
  19. data/lib/action_controller/metal/conditional_get.rb +9 -3
  20. data/lib/action_controller/metal/data_streaming.rb +5 -6
  21. data/lib/action_controller/metal/default_headers.rb +17 -0
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  23. data/lib/action_controller/metal/exceptions.rb +23 -2
  24. data/lib/action_controller/metal/flash.rb +5 -5
  25. data/lib/action_controller/metal/force_ssl.rb +15 -56
  26. data/lib/action_controller/metal/head.rb +1 -1
  27. data/lib/action_controller/metal/helpers.rb +3 -4
  28. data/lib/action_controller/metal/http_authentication.rb +20 -21
  29. data/lib/action_controller/metal/implicit_render.rb +4 -14
  30. data/lib/action_controller/metal/instrumentation.rb +3 -5
  31. data/lib/action_controller/metal/live.rb +29 -27
  32. data/lib/action_controller/metal/mime_responds.rb +13 -2
  33. data/lib/action_controller/metal/params_wrapper.rb +18 -14
  34. data/lib/action_controller/metal/redirecting.rb +5 -5
  35. data/lib/action_controller/metal/renderers.rb +4 -4
  36. data/lib/action_controller/metal/rendering.rb +2 -2
  37. data/lib/action_controller/metal/request_forgery_protection.rb +23 -12
  38. data/lib/action_controller/metal/strong_parameters.rb +63 -44
  39. data/lib/action_controller/metal/url_for.rb +1 -1
  40. data/lib/action_controller/railties/helpers.rb +1 -1
  41. data/lib/action_controller/renderer.rb +16 -3
  42. data/lib/action_controller/template_assertions.rb +1 -1
  43. data/lib/action_controller/test_case.rb +4 -6
  44. data/lib/action_dispatch.rb +4 -2
  45. data/lib/action_dispatch/http/cache.rb +14 -10
  46. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  47. data/lib/action_dispatch/http/content_security_policy.rb +28 -16
  48. data/lib/action_dispatch/http/filter_parameters.rb +8 -6
  49. data/lib/action_dispatch/http/filter_redirect.rb +1 -1
  50. data/lib/action_dispatch/http/headers.rb +1 -1
  51. data/lib/action_dispatch/http/mime_negotiation.rb +7 -5
  52. data/lib/action_dispatch/http/mime_type.rb +14 -6
  53. data/lib/action_dispatch/http/parameter_filter.rb +5 -79
  54. data/lib/action_dispatch/http/parameters.rb +13 -3
  55. data/lib/action_dispatch/http/request.rb +10 -13
  56. data/lib/action_dispatch/http/response.rb +39 -18
  57. data/lib/action_dispatch/http/upload.rb +9 -1
  58. data/lib/action_dispatch/http/url.rb +81 -81
  59. data/lib/action_dispatch/journey/formatter.rb +2 -2
  60. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
  61. data/lib/action_dispatch/journey/nodes/node.rb +9 -8
  62. data/lib/action_dispatch/journey/path/pattern.rb +8 -3
  63. data/lib/action_dispatch/journey/route.rb +5 -4
  64. data/lib/action_dispatch/journey/router.rb +0 -3
  65. data/lib/action_dispatch/journey/router/utils.rb +10 -10
  66. data/lib/action_dispatch/journey/routes.rb +0 -1
  67. data/lib/action_dispatch/journey/scanner.rb +11 -4
  68. data/lib/action_dispatch/journey/visitors.rb +1 -1
  69. data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
  70. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  71. data/lib/action_dispatch/middleware/cookies.rb +52 -74
  72. data/lib/action_dispatch/middleware/debug_exceptions.rb +39 -59
  73. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  74. data/lib/action_dispatch/middleware/debug_view.rb +68 -0
  75. data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -15
  76. data/lib/action_dispatch/middleware/flash.rb +1 -1
  77. data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
  78. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -2
  79. data/lib/action_dispatch/middleware/remote_ip.rb +9 -11
  80. data/lib/action_dispatch/middleware/request_id.rb +2 -2
  81. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -6
  82. data/lib/action_dispatch/middleware/show_exceptions.rb +1 -1
  83. data/lib/action_dispatch/middleware/ssl.rb +8 -8
  84. data/lib/action_dispatch/middleware/stack.rb +34 -2
  85. data/lib/action_dispatch/middleware/static.rb +5 -6
  86. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  88. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
  89. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  90. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  91. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  92. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
  95. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
  97. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -2
  98. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  101. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  102. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  103. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  104. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
  105. data/lib/action_dispatch/railtie.rb +7 -2
  106. data/lib/action_dispatch/request/session.rb +8 -0
  107. data/lib/action_dispatch/routing.rb +21 -20
  108. data/lib/action_dispatch/routing/inspector.rb +99 -50
  109. data/lib/action_dispatch/routing/mapper.rb +61 -39
  110. data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -4
  111. data/lib/action_dispatch/routing/route_set.rb +24 -27
  112. data/lib/action_dispatch/routing/url_for.rb +1 -0
  113. data/lib/action_dispatch/system_test_case.rb +43 -5
  114. data/lib/action_dispatch/system_testing/browser.rb +38 -7
  115. data/lib/action_dispatch/system_testing/driver.rb +10 -1
  116. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
  117. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -6
  118. data/lib/action_dispatch/testing/assertions.rb +1 -1
  119. data/lib/action_dispatch/testing/assertions/response.rb +2 -3
  120. data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
  121. data/lib/action_dispatch/testing/integration.rb +12 -5
  122. data/lib/action_dispatch/testing/request_encoder.rb +2 -2
  123. data/lib/action_dispatch/testing/test_process.rb +2 -2
  124. data/lib/action_dispatch/testing/test_response.rb +4 -32
  125. data/lib/action_pack.rb +1 -1
  126. data/lib/action_pack/gem_version.rb +3 -3
  127. metadata +29 -16
  128. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -55,11 +55,11 @@ module ActionController
55
55
  # Statements after +redirect_to+ in our controller get executed, so +redirect_to+ doesn't stop the execution of the function.
56
56
  # To terminate the execution of the function immediately after the +redirect_to+, use return.
57
57
  # redirect_to post_url(@post) and return
58
- def redirect_to(options = {}, response_status = {})
58
+ def redirect_to(options = {}, response_options = {})
59
59
  raise ActionControllerError.new("Cannot redirect to nil!") unless options
60
60
  raise AbstractController::DoubleRenderError if response_body
61
61
 
62
- self.status = _extract_redirect_to_status(options, response_status)
62
+ self.status = _extract_redirect_to_status(options, response_options)
63
63
  self.location = _compute_redirect_to_location(request, options)
64
64
  self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
65
65
  end
@@ -114,11 +114,11 @@ module ActionController
114
114
  public :_compute_redirect_to_location
115
115
 
116
116
  private
117
- def _extract_redirect_to_status(options, response_status)
117
+ def _extract_redirect_to_status(options, response_options)
118
118
  if options.is_a?(Hash) && options.key?(:status)
119
119
  Rack::Utils.status_code(options.delete(:status))
120
- elsif response_status.key?(:status)
121
- Rack::Utils.status_code(response_status[:status])
120
+ elsif response_options.key?(:status)
121
+ Rack::Utils.status_code(response_options[:status])
122
122
  else
123
123
  302
124
124
  end
@@ -157,24 +157,24 @@ module ActionController
157
157
  json = json.to_json(options) unless json.kind_of?(String)
158
158
 
159
159
  if options[:callback].present?
160
- if content_type.nil? || content_type == Mime[:json]
160
+ if media_type.nil? || media_type == Mime[:json]
161
161
  self.content_type = Mime[:js]
162
162
  end
163
163
 
164
164
  "/**/#{options[:callback]}(#{json})"
165
165
  else
166
- self.content_type ||= Mime[:json]
166
+ self.content_type = Mime[:json] if media_type.nil?
167
167
  json
168
168
  end
169
169
  end
170
170
 
171
171
  add :js do |js, options|
172
- self.content_type ||= Mime[:js]
172
+ self.content_type = Mime[:js] if media_type.nil?
173
173
  js.respond_to?(:to_js) ? js.to_js(options) : js
174
174
  end
175
175
 
176
176
  add :xml do |xml, options|
177
- self.content_type ||= Mime[:xml]
177
+ self.content_type = Mime[:xml] if media_type.nil?
178
178
  xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml
179
179
  end
180
180
  end
@@ -40,7 +40,7 @@ module ActionController
40
40
  def render_to_string(*)
41
41
  result = super
42
42
  if result.respond_to?(:each)
43
- string = "".dup
43
+ string = +""
44
44
  result.each { |r| string << r }
45
45
  string
46
46
  else
@@ -73,7 +73,7 @@ module ActionController
73
73
  end
74
74
 
75
75
  def _set_rendered_content_type(format)
76
- if format && !response.content_type
76
+ if format && !response.media_type
77
77
  self.content_type = format.to_s
78
78
  end
79
79
  end
@@ -3,7 +3,6 @@
3
3
  require "rack/session/abstract/id"
4
4
  require "action_controller/metal/exceptions"
5
5
  require "active_support/security_utils"
6
- require "active_support/core_ext/string/strip"
7
6
 
8
7
  module ActionController #:nodoc:
9
8
  class InvalidAuthenticityToken < ActionControllerError #:nodoc:
@@ -18,7 +17,7 @@ module ActionController #:nodoc:
18
17
  # access. When a request reaches your application, \Rails verifies the received
19
18
  # token with the token in the session. All requests are checked except GET requests
20
19
  # as these should be idempotent. Keep in mind that all session-oriented requests
21
- # should be CSRF protected, including JavaScript and HTML requests.
20
+ # are CSRF protected by default, including JavaScript and HTML requests.
22
21
  #
23
22
  # Since HTML and JavaScript requests are typically made from the browser, we
24
23
  # need to ensure to verify request authenticity for the web browser. We can
@@ -31,16 +30,23 @@ module ActionController #:nodoc:
31
30
  # URL on your site. When your JavaScript response loads on their site, it executes.
32
31
  # With carefully crafted JavaScript on their end, sensitive data in your JavaScript
33
32
  # response may be extracted. To prevent this, only XmlHttpRequest (known as XHR or
34
- # Ajax) requests are allowed to make GET requests for JavaScript responses.
33
+ # Ajax) requests are allowed to make requests for JavaScript responses.
35
34
  #
36
- # It's important to remember that XML or JSON requests are also affected and if
37
- # you're building an API you should change forgery protection method in
35
+ # It's important to remember that XML or JSON requests are also checked by default. If
36
+ # you're building an API or an SPA you could change forgery protection method in
38
37
  # <tt>ApplicationController</tt> (by default: <tt>:exception</tt>):
39
38
  #
40
39
  # class ApplicationController < ActionController::Base
41
40
  # protect_from_forgery unless: -> { request.format.json? }
42
41
  # end
43
42
  #
43
+ # It is generally safe to exclude XHR requests from CSRF protection
44
+ # (like the code snippet above does), because XHR requests can only be made from
45
+ # the same origin. Note however that any cross-origin third party domain
46
+ # allowed via {CORS}[https://en.wikipedia.org/wiki/Cross-origin_resource_sharing]
47
+ # will also be able to create XHR requests. Be sure to check your
48
+ # CORS configuration before disabling forgery protection for XHR.
49
+ #
44
50
  # CSRF protection is turned on with the <tt>protect_from_forgery</tt> method.
45
51
  # By default <tt>protect_from_forgery</tt> protects your session with
46
52
  # <tt>:null_session</tt> method, which provides an empty session
@@ -55,7 +61,7 @@ module ActionController #:nodoc:
55
61
  # <tt>csrf_meta_tags</tt> in the HTML +head+.
56
62
  #
57
63
  # Learn more about CSRF attacks and securing your application in the
58
- # {Ruby on Rails Security Guide}[http://guides.rubyonrails.org/security.html].
64
+ # {Ruby on Rails Security Guide}[https://guides.rubyonrails.org/security.html].
59
65
  module RequestForgeryProtection
60
66
  extend ActiveSupport::Concern
61
67
 
@@ -276,7 +282,7 @@ module ActionController #:nodoc:
276
282
 
277
283
  # Check for cross-origin JavaScript responses.
278
284
  def non_xhr_javascript_response? # :doc:
279
- content_type =~ %r(\Atext/javascript) && !request.xhr?
285
+ %r(\A(?:text|application)/javascript).match?(media_type) && !request.xhr?
280
286
  end
281
287
 
282
288
  AUTHENTICITY_TOKEN_LENGTH = 32
@@ -401,9 +407,14 @@ module ActionController #:nodoc:
401
407
  end
402
408
 
403
409
  def xor_byte_strings(s1, s2) # :doc:
404
- s2_bytes = s2.bytes
405
- s1.each_byte.with_index { |c1, i| s2_bytes[i] ^= c1 }
406
- s2_bytes.pack("C*")
410
+ s2 = s2.dup
411
+ size = s1.bytesize
412
+ i = 0
413
+ while i < size
414
+ s2.setbyte(i, s1.getbyte(i) ^ s2.getbyte(i))
415
+ i += 1
416
+ end
417
+ s2
407
418
  end
408
419
 
409
420
  # The form's authenticity parameter. Override to provide your own.
@@ -416,11 +427,11 @@ module ActionController #:nodoc:
416
427
  allow_forgery_protection
417
428
  end
418
429
 
419
- NULL_ORIGIN_MESSAGE = <<-MSG.strip_heredoc
430
+ NULL_ORIGIN_MESSAGE = <<~MSG
420
431
  The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually
421
432
  means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that
422
433
  refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the
423
- best solution is to change your referrer policy to something less strict like same-origin or strict-same-origin.
434
+ best solution is to change your referrer policy to something less strict like same-origin or strict-origin.
424
435
  If you cannot change the referrer policy, you can disable origin checking with the
425
436
  Rails.application.config.action_controller.forgery_protection_origin_check setting.
426
437
  MSG
@@ -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"
@@ -59,7 +57,7 @@ module ActionController
59
57
 
60
58
  # == Action Controller \Parameters
61
59
  #
62
- # Allows you to choose which attributes should be whitelisted for mass updating
60
+ # Allows you to choose which attributes should be permitted for mass updating
63
61
  # and thus prevent accidentally exposing that which shouldn't be exposed.
64
62
  # Provides two methods for this purpose: #require and #permit. The former is
65
63
  # used to mark parameters as required. The latter is used to set the parameter
@@ -133,6 +131,15 @@ module ActionController
133
131
  #
134
132
  # Returns a hash that can be used as the JSON representation for the parameters.
135
133
 
134
+ ##
135
+ # :method: each_key
136
+ #
137
+ # :call-seq:
138
+ # each_key()
139
+ #
140
+ # Calls block once for each key in the parameters, passing the key.
141
+ # If no block is given, an enumerator is returned instead.
142
+
136
143
  ##
137
144
  # :method: empty?
138
145
  #
@@ -205,7 +212,7 @@ module ActionController
205
212
  #
206
213
  # Returns a new array of the values of the parameters.
207
214
  delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
208
- :as_json, :to_s, to: :@parameters
215
+ :as_json, :to_s, :each_key, to: :@parameters
209
216
 
210
217
  # By default, never raise an UnpermittedParameters exception if these
211
218
  # params are present. The default includes both 'controller' and 'action'
@@ -340,6 +347,14 @@ module ActionController
340
347
  end
341
348
  alias_method :each, :each_pair
342
349
 
350
+ # Convert all hashes in values into parameters, then yield each value in
351
+ # the same way as <tt>Hash#each_value</tt>.
352
+ def each_value(&block)
353
+ @parameters.each_pair do |key, value|
354
+ yield convert_hashes_to_parameters(key, value)
355
+ end
356
+ end
357
+
343
358
  # Attribute that keeps track of converted arrays, if any, to avoid double
344
359
  # looping in the common use case permit + mass-assignment. Defined in a
345
360
  # method to instantiate it only if needed.
@@ -506,7 +521,7 @@ module ActionController
506
521
  #
507
522
  # Note that if you use +permit+ in a key that points to a hash,
508
523
  # it won't allow all the hash. You also need to specify which
509
- # attributes inside the hash should be whitelisted.
524
+ # attributes inside the hash should be permitted.
510
525
  #
511
526
  # params = ActionController::Parameters.new({
512
527
  # person: {
@@ -583,20 +598,18 @@ module ActionController
583
598
  )
584
599
  end
585
600
 
586
- if Hash.method_defined?(:dig)
587
- # Extracts the nested parameter from the given +keys+ by calling +dig+
588
- # at each step. Returns +nil+ if any intermediate step is +nil+.
589
- #
590
- # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
591
- # params.dig(:foo, :bar, :baz) # => 1
592
- # params.dig(:foo, :zot, :xyz) # => nil
593
- #
594
- # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
595
- # params2.dig(:foo, 1) # => 11
596
- def dig(*keys)
597
- convert_hashes_to_parameters(keys.first, @parameters[keys.first])
598
- @parameters.dig(*keys)
599
- end
601
+ # Extracts the nested parameter from the given +keys+ by calling +dig+
602
+ # at each step. Returns +nil+ if any intermediate step is +nil+.
603
+ #
604
+ # params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
605
+ # params.dig(:foo, :bar, :baz) # => 1
606
+ # params.dig(:foo, :zot, :xyz) # => nil
607
+ #
608
+ # params2 = ActionController::Parameters.new(foo: [10, 11, 12])
609
+ # params2.dig(:foo, 1) # => 11
610
+ def dig(*keys)
611
+ convert_hashes_to_parameters(keys.first, @parameters[keys.first])
612
+ @parameters.dig(*keys)
600
613
  end
601
614
 
602
615
  # Returns a new <tt>ActionController::Parameters</tt> instance that
@@ -660,18 +673,16 @@ module ActionController
660
673
  # Returns a new <tt>ActionController::Parameters</tt> instance with the
661
674
  # results of running +block+ once for every key. The values are unchanged.
662
675
  def transform_keys(&block)
663
- if block
664
- new_instance_with_inherited_permitted_status(
665
- @parameters.transform_keys(&block)
666
- )
667
- else
668
- @parameters.transform_keys
669
- end
676
+ return to_enum(:transform_keys) unless block_given?
677
+ new_instance_with_inherited_permitted_status(
678
+ @parameters.transform_keys(&block)
679
+ )
670
680
  end
671
681
 
672
682
  # Performs keys transformation and returns the altered
673
683
  # <tt>ActionController::Parameters</tt> instance.
674
684
  def transform_keys!(&block)
685
+ return to_enum(:transform_keys!) unless block_given?
675
686
  @parameters.transform_keys!(&block)
676
687
  self
677
688
  end
@@ -781,7 +792,7 @@ module ActionController
781
792
  @permitted = coder.map["ivars"][:@permitted]
782
793
  when "!ruby/object:ActionController::Parameters"
783
794
  # YAML's Object format. Only needed because of the format
784
- # backwardscompability above, otherwise equivalent to YAML's initialization.
795
+ # backwards compatibility above, otherwise equivalent to YAML's initialization.
785
796
  @parameters, @permitted = coder.map["parameters"], coder.map["permitted"]
786
797
  end
787
798
  end
@@ -796,9 +807,7 @@ module ActionController
796
807
  protected
797
808
  attr_reader :parameters
798
809
 
799
- def permitted=(new_permitted)
800
- @permitted = new_permitted
801
- end
810
+ attr_writer :permitted
802
811
 
803
812
  def fields_for_style?
804
813
  @parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
@@ -909,15 +918,28 @@ module ActionController
909
918
  PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) }
910
919
  end
911
920
 
912
- def permitted_scalar_filter(params, key)
913
- if has_key?(key) && permitted_scalar?(self[key])
914
- params[key] = self[key]
921
+ # Adds existing keys to the params if their values are scalar.
922
+ #
923
+ # For example:
924
+ #
925
+ # puts self.keys #=> ["zipcode(90210i)"]
926
+ # params = {}
927
+ #
928
+ # permitted_scalar_filter(params, "zipcode")
929
+ #
930
+ # puts params.keys # => ["zipcode"]
931
+ def permitted_scalar_filter(params, permitted_key)
932
+ permitted_key = permitted_key.to_s
933
+
934
+ if has_key?(permitted_key) && permitted_scalar?(self[permitted_key])
935
+ params[permitted_key] = self[permitted_key]
915
936
  end
916
937
 
917
- keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k|
918
- if permitted_scalar?(self[k])
919
- params[k] = self[k]
920
- end
938
+ each_key do |key|
939
+ next unless key =~ /\(\d+[if]?\)\z/
940
+ next unless $~.pre_match == permitted_key
941
+
942
+ params[key] = self[key] if permitted_scalar?(self[key])
921
943
  end
922
944
  end
923
945
 
@@ -1002,8 +1024,8 @@ module ActionController
1002
1024
  #
1003
1025
  # It provides an interface for protecting attributes from end-user
1004
1026
  # assignment. This makes Action Controller parameters forbidden
1005
- # to be used in Active Model mass assignment until they have been
1006
- # whitelisted.
1027
+ # to be used in Active Model mass assignment until they have been explicitly
1028
+ # enumerated.
1007
1029
  #
1008
1030
  # In addition, parameters can be marked as required and flow through a
1009
1031
  # predefined raise/rescue flow to end up as a <tt>400 Bad Request</tt> with no
@@ -1039,7 +1061,7 @@ module ActionController
1039
1061
  # end
1040
1062
  #
1041
1063
  # In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
1042
- # will need to specify which nested attributes should be whitelisted. You might want
1064
+ # will need to specify which nested attributes should be permitted. You might want
1043
1065
  # to allow +:id+ and +:_destroy+, see ActiveRecord::NestedAttributes for more information.
1044
1066
  #
1045
1067
  # class Person
@@ -1057,7 +1079,7 @@ module ActionController
1057
1079
  # private
1058
1080
  #
1059
1081
  # def person_params
1060
- # # It's mandatory to specify the nested attributes that should be whitelisted.
1082
+ # # It's mandatory to specify the nested attributes that should be permitted.
1061
1083
  # # If you use `permit` with just the key that points to the nested attributes hash,
1062
1084
  # # it will return an empty hash.
1063
1085
  # params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
@@ -1067,9 +1089,6 @@ module ActionController
1067
1089
  # See ActionController::Parameters.require and ActionController::Parameters.permit
1068
1090
  # for more information.
1069
1091
  module StrongParameters
1070
- extend ActiveSupport::Concern
1071
- include ActiveSupport::Rescuable
1072
-
1073
1092
  # Returns a new ActionController::Parameters object that
1074
1093
  # has been instantiated with the <tt>request.parameters</tt>.
1075
1094
  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
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/hash/keys"
4
-
5
3
  module ActionController
6
4
  # ActionController::Renderer allows you to render arbitrary templates
7
5
  # without requirement of being in controller actions.
@@ -71,6 +69,21 @@ module ActionController
71
69
  end
72
70
 
73
71
  # Render templates with any options from ActionController::Base#render_to_string.
72
+ #
73
+ # The primary options are:
74
+ # * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt> for details.
75
+ # * <tt>:file</tt> - Renders an explicit template file. Add <tt>:locals</tt> to pass in, if so desired.
76
+ # It shouldn’t be used directly with unsanitized user input due to lack of validation.
77
+ # * <tt>:inline</tt> - Renders an ERB template string.
78
+ # * <tt>:plain</tt> - Renders provided text and sets the content type as <tt>text/plain</tt>.
79
+ # * <tt>:html</tt> - Renders the provided HTML safe string, otherwise
80
+ # performs HTML escape on the string first. Sets the content type as <tt>text/html</tt>.
81
+ # * <tt>:json</tt> - Renders the provided hash or object in JSON. You don't
82
+ # need to call <tt>.to_json</tt> on the object you want to render.
83
+ # * <tt>:body</tt> - Renders provided text and sets content type of <tt>text/plain</tt>.
84
+ #
85
+ # If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, the default is
86
+ # to render a partial and use the second parameter as the locals hash.
74
87
  def render(*args)
75
88
  raise "missing controller" unless controller
76
89
 
@@ -103,7 +116,7 @@ module ActionController
103
116
 
104
117
  RACK_VALUE_TRANSLATION = {
105
118
  https: ->(v) { v ? "on" : "off" },
106
- method: ->(v) { v.upcase },
119
+ method: ->(v) { -v.upcase },
107
120
  }
108
121
 
109
122
  def rack_key_for(key)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionController
4
- module TemplateAssertions
4
+ module TemplateAssertions # :nodoc:
5
5
  def assert_template(options = {}, message = nil)
6
6
  raise NoMethodError,
7
7
  "assert_template has been extracted to a gem. To continue using it,