actionpack 8.0.1 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e4dddbd1aa72f74822805435b23f5a92c79410529fc9e27048cb00d5092a612
4
- data.tar.gz: 656ce52971952bc500713fe2892a980426ba65612907138c4ca0159951dbf338
3
+ metadata.gz: 14abb1a6b812efa40da31cf30c3171405982457ed80984d231dae2af352f43f4
4
+ data.tar.gz: 3e934fe98cf59aa4727eb76b0f13567861fe01c04dbc6cd9c4e313b165a0a64e
5
5
  SHA512:
6
- metadata.gz: 814ef02acc2f6218c64045ba3e000fc379657b4cea039991a0fabe96792b0f77a9d843ba9592d04156c346d51b92c91535f4f9e7cde014ee03ffebe20e9292f7
7
- data.tar.gz: 6568066218b50285be5baac02247119c5d296751e5f437ba6efe0131630f68cfe767656e0e7da485529747f562bebeb7282a8fa4d5a25e473af787da2a6e0c72
6
+ metadata.gz: dde2e5f17a6d54ae692f64ec2d05a3dc8e54d4fb30d97dd4b1fa3e4c7363d1132facf04286c1b3f25ffdb78f8302eafa7a6c13d027b890589813e4e60e6f5e77
7
+ data.tar.gz: 773181339ec3539e73607f4e1588082893c3ac38d54e6c32a930ccf85bcffb41c95ad568a6bbe00bbc41967f98ed964d3200880a3c1f7b1dbfafeef405d8b1b5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ ## Rails 8.0.2 (March 12, 2025) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 8.0.2 (March 12, 2025) ##
7
+
8
+ * Improve `with_routing` test helper to not rebuild the middleware stack.
9
+
10
+ Otherwise some middleware configuration could be lost.
11
+
12
+ *Édouard Chin*
13
+
14
+ * Add resource name to the `ArgumentError` that's raised when invalid `:only` or `:except` options are given to `#resource` or `#resources`
15
+
16
+ This makes it easier to locate the source of the problem, especially for routes drawn by gems.
17
+
18
+ Before:
19
+ ```
20
+ :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
21
+ ```
22
+
23
+ After:
24
+ ```
25
+ Route `resources :products` - :only and :except must include only [:index, :create, :new, :show, :update, :destroy, :edit], but also included [:foo, :bar]
26
+ ```
27
+
28
+ *Jeremy Green*
29
+
30
+ * Fix `url_for` to handle `:path_params` gracefully when it's not a `Hash`.
31
+
32
+ Prevents various security scanners from causing exceptions.
33
+
34
+ *Martin Emde*
35
+
36
+ * Fix `ActionDispatch::Executor` to unwrap exceptions like other error reporting middlewares.
37
+
38
+ *Jean Boussier*
39
+
40
+
1
41
  ## Rails 8.0.1 (December 13, 2024) ##
2
42
 
3
43
  * Add `ActionDispatch::Request::Session#store` method to conform Rack spec.
@@ -307,9 +307,8 @@ module ActionController
307
307
  error = e
308
308
  end
309
309
  ensure
310
- # Ensure we clean up any thread locals we copied so that the thread can reused.
311
310
  ActiveSupport::IsolatedExecutionState.clear
312
- locals.each { |k, _| t2[k] = nil }
311
+ clean_up_thread_locals(locals, t2)
313
312
 
314
313
  @_response.commit!
315
314
  end
@@ -383,6 +382,11 @@ module ActionController
383
382
  end
384
383
  end
385
384
 
385
+ # Ensure we clean up any thread locals we copied so that the thread can reused.
386
+ def clean_up_thread_locals(locals, thread) # :nodoc:
387
+ locals.each { |k, _| thread[k] = nil }
388
+ end
389
+
386
390
  def self.live_thread_pool_executor
387
391
  @live_thread_pool_executor ||= Concurrent::CachedThreadPool.new(name: "action_controller.live")
388
392
  end
@@ -198,14 +198,14 @@ module ActionController
198
198
  # # enables the parameter wrapper for XML format
199
199
  #
200
200
  # wrap_parameters :person
201
- # # wraps parameters into +params[:person]+ hash
201
+ # # wraps parameters into params[:person] hash
202
202
  #
203
203
  # wrap_parameters Person
204
204
  # # wraps parameters by determining the wrapper key from Person class
205
- # # (+person+, in this case) and the list of attribute names
205
+ # # (:person, in this case) and the list of attribute names
206
206
  #
207
207
  # wrap_parameters include: [:username, :title]
208
- # # wraps only +:username+ and +:title+ attributes from parameters.
208
+ # # wraps only :username and :title attributes from parameters.
209
209
  #
210
210
  # wrap_parameters false
211
211
  # # disables parameters wrapping for this controller altogether.
@@ -142,6 +142,7 @@ module ActionController # :nodoc:
142
142
  #
143
143
  #
144
144
  # Built-in unverified request handling methods are:
145
+ #
145
146
  # * `:exception` - Raises ActionController::InvalidAuthenticityToken
146
147
  # exception.
147
148
  # * `:reset_session` - Resets the session.
@@ -170,6 +171,7 @@ module ActionController # :nodoc:
170
171
  #
171
172
  #
172
173
  # Built-in session token strategies are:
174
+ #
173
175
  # * `:session` - Store the CSRF token in the session. Used as default if
174
176
  # `:store` option is not specified.
175
177
  # * `:cookie` - Store the CSRF token in an encrypted cookie.
@@ -498,7 +500,7 @@ module ActionController # :nodoc:
498
500
  # Checks the client's masked token to see if it matches the session token.
499
501
  # Essentially the inverse of `masked_authenticity_token`.
500
502
  def valid_authenticity_token?(session, encoded_masked_token) # :doc:
501
- if encoded_masked_token.nil? || encoded_masked_token.empty? || !encoded_masked_token.is_a?(String)
503
+ if !encoded_masked_token.is_a?(String) || encoded_masked_token.empty?
502
504
  return false
503
505
  end
504
506
 
@@ -765,7 +765,7 @@ module ActionController
765
765
  #
766
766
  # params = ActionController::Parameters.new(tags: ["rails", "parameters"])
767
767
  # permitted = params.expect(tags: [])
768
- # permitted.permitted? # => true
768
+ # permitted # => ["rails", "parameters"]
769
769
  # permitted.is_a?(Array) # => true
770
770
  # permitted.size # => 2
771
771
  #
@@ -1287,9 +1287,6 @@ module ActionController
1287
1287
  keys - params.keys - always_permitted_parameters
1288
1288
  end
1289
1289
 
1290
- #
1291
- # --- Filtering ----------------------------------------------------------
1292
- #
1293
1290
  # This is a list of permitted scalar types that includes the ones supported in
1294
1291
  # XML and JSON requests.
1295
1292
  #
@@ -29,6 +29,14 @@ module ActionController
29
29
  yield
30
30
  end
31
31
 
32
+ # Because of the above, we need to prevent the clearing of thread locals, since
33
+ # no new thread is actually spawned in the test environment.
34
+ alias_method :original_clean_up_thread_locals, :clean_up_thread_locals
35
+
36
+ silence_redefinition_of_method :clean_up_thread_locals
37
+ def clean_up_thread_locals(*args) # :nodoc:
38
+ end
39
+
32
40
  # Avoid a deadlock from the queue filling up
33
41
  Buffer.queue_size = nil
34
42
  end
@@ -139,7 +139,7 @@ module ActionDispatch
139
139
 
140
140
  # Populate the HTTP method lookup cache.
141
141
  HTTP_METHODS.each { |method|
142
- HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
142
+ HTTP_METHOD_LOOKUP[method] = method.downcase.underscore.to_sym
143
143
  }
144
144
 
145
145
  alias raw_request_method request_method # :nodoc:
@@ -243,8 +243,9 @@ module ActionDispatch
243
243
  #
244
244
  # send_early_hints("link" => "</style.css>; rel=preload; as=style,</script.js>; rel=preload")
245
245
  #
246
- # If you are using `javascript_include_tag` or `stylesheet_link_tag` the Early
247
- # Hints headers are included by default if supported.
246
+ # If you are using {javascript_include_tag}[rdoc-ref:ActionView::Helpers::AssetTagHelper#javascript_include_tag]
247
+ # or {stylesheet_link_tag}[rdoc-ref:ActionView::Helpers::AssetTagHelper#stylesheet_link_tag]
248
+ # the Early Hints headers are included by default if supported.
248
249
  def send_early_hints(links)
249
250
  env["rack.early_hints"]&.call(links)
250
251
  end
@@ -60,8 +60,13 @@ module ActionDispatch
60
60
 
61
61
  def generate(name, options, path_parameters)
62
62
  original_options = options.dup
63
- path_params = options.delete(:path_params) || {}
64
- options = path_params.merge(options)
63
+ path_params = options.delete(:path_params)
64
+ if path_params.is_a?(Hash)
65
+ options = path_params.merge(options)
66
+ else
67
+ path_params = nil
68
+ options = options.dup
69
+ end
65
70
  constraints = path_parameters.merge(options)
66
71
  missing_keys = nil
67
72
 
@@ -79,7 +84,7 @@ module ActionDispatch
79
84
  # top-level params' normal behavior of generating query_params should be
80
85
  # preserved even if the same key is also a bind_param
81
86
  parameterized_parts.key?(key) || route.defaults.key?(key) ||
82
- (path_params.key?(key) && !original_options.key?(key))
87
+ (path_params&.key?(key) && !original_options.key?(key))
83
88
  end
84
89
 
85
90
  defaults = route.defaults
@@ -21,8 +21,11 @@ module ActionDispatch
21
21
  end
22
22
 
23
23
  returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
24
- rescue => error
25
- @executor.error_reporter.report(error, handled: false, source: "application.action_dispatch")
24
+ rescue Exception => error
25
+ request = ActionDispatch::Request.new env
26
+ backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
27
+ wrapper = ExceptionWrapper.new(backtrace_cleaner, error)
28
+ @executor.error_reporter.report(wrapper.unwrapped_exception, handled: false, source: "application.action_dispatch")
26
29
  raise
27
30
  ensure
28
31
  state.complete! unless returned
@@ -840,7 +840,7 @@ module ActionDispatch
840
840
  #
841
841
  # Takes same options as `Base#match` and `Resources#resources`.
842
842
  #
843
- # # route /posts (without the prefix /admin) to +Admin::PostsController+
843
+ # # route /posts (without the prefix /admin) to Admin::PostsController
844
844
  # scope module: "admin" do
845
845
  # resources :posts
846
846
  # end
@@ -850,7 +850,7 @@ module ActionDispatch
850
850
  # resources :posts
851
851
  # end
852
852
  #
853
- # # prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
853
+ # # prefix the routing helper name: sekret_posts_path instead of posts_path
854
854
  # scope as: "sekret" do
855
855
  # resources :posts
856
856
  # end
@@ -949,12 +949,12 @@ module ActionDispatch
949
949
  # resources :posts
950
950
  # end
951
951
  #
952
- # # maps to +Sekret::PostsController+ rather than +Admin::PostsController+
952
+ # # maps to Sekret::PostsController rather than Admin::PostsController
953
953
  # namespace :admin, module: "sekret" do
954
954
  # resources :posts
955
955
  # end
956
956
  #
957
- # # generates +sekret_posts_path+ rather than +admin_posts_path+
957
+ # # generates sekret_posts_path rather than admin_posts_path
958
958
  # namespace :admin, as: "sekret" do
959
959
  # resources :posts
960
960
  # end
@@ -1181,7 +1181,8 @@ module ActionDispatch
1181
1181
 
1182
1182
  valid_actions = self.class.default_actions(false) # ignore api_only for this validation
1183
1183
  if invalid_actions = invalid_only_except_options(options, valid_actions).presence
1184
- raise ArgumentError, ":only and :except must include only #{valid_actions}, but also included #{invalid_actions}"
1184
+ error_prefix = "Route `resource#{"s" unless singleton?} :#{entities}`"
1185
+ raise ArgumentError, "#{error_prefix} - :only and :except must include only #{valid_actions}, but also included #{invalid_actions}"
1185
1186
  end
1186
1187
 
1187
1188
  @name = entities.to_s
@@ -1509,7 +1510,7 @@ module ActionDispatch
1509
1510
  #
1510
1511
  # ### Examples
1511
1512
  #
1512
- # # routes call +Admin::PostsController+
1513
+ # # routes call Admin::PostsController
1513
1514
  # resources :posts, module: "admin"
1514
1515
  #
1515
1516
  # # resource actions are at /admin/posts.
@@ -5,6 +5,7 @@
5
5
  require "uri"
6
6
  require "active_support/core_ext/hash/indifferent_access"
7
7
  require "active_support/core_ext/string/access"
8
+ require "active_support/core_ext/module/redefine_method"
8
9
  require "action_controller/metal/exceptions"
9
10
 
10
11
  module ActionDispatch
@@ -20,38 +21,43 @@ module ActionDispatch
20
21
  module ClassMethods
21
22
  def with_routing(&block)
22
23
  old_routes = nil
24
+ old_routes_call_method = nil
23
25
  old_integration_session = nil
24
26
 
25
27
  setup do
26
28
  old_routes = app.routes
29
+ old_routes_call_method = old_routes.method(:call)
27
30
  old_integration_session = integration_session
28
31
  create_routes(&block)
29
32
  end
30
33
 
31
34
  teardown do
32
- reset_routes(old_routes, old_integration_session)
35
+ reset_routes(old_routes, old_routes_call_method, old_integration_session)
33
36
  end
34
37
  end
35
38
  end
36
39
 
37
40
  def with_routing(&block)
38
41
  old_routes = app.routes
42
+ old_routes_call_method = old_routes.method(:call)
39
43
  old_integration_session = integration_session
40
44
  create_routes(&block)
41
45
  ensure
42
- reset_routes(old_routes, old_integration_session)
46
+ reset_routes(old_routes, old_routes_call_method, old_integration_session)
43
47
  end
44
48
 
45
49
  private
46
50
  def create_routes
47
51
  app = self.app
48
52
  routes = ActionDispatch::Routing::RouteSet.new
49
- rack_app = app.config.middleware.build(routes)
53
+
54
+ @original_routes ||= app.routes
55
+ @original_routes.singleton_class.redefine_method(:call, &routes.method(:call))
56
+
50
57
  https = integration_session.https?
51
58
  host = integration_session.host
52
59
 
53
60
  app.instance_variable_set(:@routes, routes)
54
- app.instance_variable_set(:@app, rack_app)
55
61
  @integration_session = Class.new(ActionDispatch::Integration::Session) do
56
62
  include app.routes.url_helpers
57
63
  include app.routes.mounted_helpers
@@ -63,11 +69,9 @@ module ActionDispatch
63
69
  yield routes
64
70
  end
65
71
 
66
- def reset_routes(old_routes, old_integration_session)
67
- old_rack_app = app.config.middleware.build(old_routes)
68
-
72
+ def reset_routes(old_routes, old_routes_call_method, old_integration_session)
69
73
  app.instance_variable_set(:@routes, old_routes)
70
- app.instance_variable_set(:@app, old_rack_app)
74
+ @original_routes.singleton_class.redefine_method(:call, &old_routes_call_method)
71
75
  @integration_session = old_integration_session
72
76
  @routes = old_routes
73
77
  end
@@ -549,7 +549,7 @@ module ActionDispatch
549
549
  # https!(false)
550
550
  # get "/articles/all"
551
551
  # assert_response :success
552
- # assert_select 'h1', 'Articles'
552
+ # assert_dom 'h1', 'Articles'
553
553
  # end
554
554
  # end
555
555
  #
@@ -588,7 +588,7 @@ module ActionDispatch
588
588
  # def browses_site
589
589
  # get "/products/all"
590
590
  # assert_response :success
591
- # assert_select 'h1', 'Products'
591
+ # assert_dom 'h1', 'Products'
592
592
  # end
593
593
  # end
594
594
  #
@@ -11,7 +11,7 @@ module ActionPack
11
11
  module VERSION
12
12
  MAJOR = 8
13
13
  MINOR = 0
14
- TINY = 1
14
+ TINY = 2
15
15
  PRE = nil
16
16
 
17
17
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.1
4
+ version: 8.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-13 00:00:00.000000000 Z
10
+ date: 2025-03-12 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - '='
18
17
  - !ruby/object:Gem::Version
19
- version: 8.0.1
18
+ version: 8.0.2
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
- version: 8.0.1
25
+ version: 8.0.2
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: nokogiri
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -128,28 +127,28 @@ dependencies:
128
127
  requirements:
129
128
  - - '='
130
129
  - !ruby/object:Gem::Version
131
- version: 8.0.1
130
+ version: 8.0.2
132
131
  type: :runtime
133
132
  prerelease: false
134
133
  version_requirements: !ruby/object:Gem::Requirement
135
134
  requirements:
136
135
  - - '='
137
136
  - !ruby/object:Gem::Version
138
- version: 8.0.1
137
+ version: 8.0.2
139
138
  - !ruby/object:Gem::Dependency
140
139
  name: activemodel
141
140
  requirement: !ruby/object:Gem::Requirement
142
141
  requirements:
143
142
  - - '='
144
143
  - !ruby/object:Gem::Version
145
- version: 8.0.1
144
+ version: 8.0.2
146
145
  type: :development
147
146
  prerelease: false
148
147
  version_requirements: !ruby/object:Gem::Requirement
149
148
  requirements:
150
149
  - - '='
151
150
  - !ruby/object:Gem::Version
152
- version: 8.0.1
151
+ version: 8.0.2
153
152
  description: Web apps on Rails. Simple, battle-tested conventions for building and
154
153
  testing MVC web applications. Works with any Rack-compatible server.
155
154
  email: david@loudthinking.com
@@ -350,12 +349,11 @@ licenses:
350
349
  - MIT
351
350
  metadata:
352
351
  bug_tracker_uri: https://github.com/rails/rails/issues
353
- changelog_uri: https://github.com/rails/rails/blob/v8.0.1/actionpack/CHANGELOG.md
354
- documentation_uri: https://api.rubyonrails.org/v8.0.1/
352
+ changelog_uri: https://github.com/rails/rails/blob/v8.0.2/actionpack/CHANGELOG.md
353
+ documentation_uri: https://api.rubyonrails.org/v8.0.2/
355
354
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
356
- source_code_uri: https://github.com/rails/rails/tree/v8.0.1/actionpack
355
+ source_code_uri: https://github.com/rails/rails/tree/v8.0.2/actionpack
357
356
  rubygems_mfa_required: 'true'
358
- post_install_message:
359
357
  rdoc_options: []
360
358
  require_paths:
361
359
  - lib
@@ -371,8 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
371
369
  version: '0'
372
370
  requirements:
373
371
  - none
374
- rubygems_version: 3.5.22
375
- signing_key:
372
+ rubygems_version: 3.6.2
376
373
  specification_version: 4
377
374
  summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
378
375
  test_files: []