actionpack 6.1.2 → 6.1.4

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e18f4e0dba4fd1daa12ad504b7846ed7c35d319d793d8a999719c5f454a3a55
4
- data.tar.gz: 34eca75e2ce98348b71a0138e46ff0bcbd3b2bd26888eff928c15cb5b20779a7
3
+ metadata.gz: 9ecbd6190263018a55d9baa5737fbb8cadbcfe576eab8a37abe85f243bf7280f
4
+ data.tar.gz: 3eb5afac5cae0df74480ded35e48956a41b4017e43f9dfb7e895557ebf2efd02
5
5
  SHA512:
6
- metadata.gz: 73a46bd410d9b4d54b56d19c0f0ac5d47ac799566ba950af6bfeff17cdc370336cccd9c4b46ab8ab8dc9fca16d30b808193d496f05374f1dfd78fdd5b3b5753f
7
- data.tar.gz: ce290325486805965e58919f0aabc7a702604a0495eb7028eb94be089b82ec9684eec54472842a72eabc9b79656f0012887cf217f82cf4ca0bf2e546634adadc
6
+ metadata.gz: d25fc0df75affc20fce6891e4da46226a851b48f4379b491fa887b194866a0d2f25f619f0401ffa524bd14369a0f5705f3ae8d12ea513976c48a3101f1327925
7
+ data.tar.gz: e7bc0083bb78130cbb4d2b0d421fdc69c146b7040e64da4d2ed0c18715f0a94b1c5d9dc2447439c31c7e63682dab1b03e5d0db0c6a14bb020e99a5da44ae9728
data/CHANGELOG.md CHANGED
@@ -1,3 +1,86 @@
1
+ ## Rails 6.1.4 (June 24, 2021) ##
2
+
3
+ * Ignore file fixtures on `db:fixtures:load`
4
+
5
+ *Kevin Sjöberg*
6
+
7
+ * Fix ActionController::Live controller test deadlocks by removing the body buffer size limit for tests.
8
+
9
+ *Dylan Thacker-Smith*
10
+
11
+ * Correctly place optional path parameter booleans.
12
+
13
+ Previously, if you specify a url parameter that is part of the path as false it would include that part
14
+ of the path as parameter for example:
15
+
16
+ ```
17
+ get "(/optional/:optional_id)/things" => "foo#foo", as: :things
18
+ things_path(optional_id: false) # => /things?optional_id=false
19
+ ```
20
+
21
+ After this change, true and false will be treated the same when used as optional path parameters. Meaning now:
22
+
23
+ ```
24
+ get '(this/:my_bool)/that' as: :that
25
+
26
+ that_path(my_bool: true) # => `/this/true/that`
27
+ that_path(my_bool: false) # => `/this/false/that`
28
+ ```
29
+
30
+ *Adam Hess*
31
+
32
+ * Add support for 'private, no-store' Cache-Control headers.
33
+
34
+ Previously, 'no-store' was exclusive; no other directives could be specified.
35
+
36
+ *Alex Smith*
37
+
38
+
39
+ ## Rails 6.1.3.2 (May 05, 2021) ##
40
+
41
+ * Prevent open redirects by correctly escaping the host allow list
42
+ CVE-2021-22903
43
+
44
+ * Prevent catastrophic backtracking during mime parsing
45
+ CVE-2021-22902
46
+
47
+ * Prevent regex DoS in HTTP token authentication
48
+ CVE-2021-22904
49
+
50
+ * Prevent string polymorphic route arguments.
51
+
52
+ `url_for` supports building polymorphic URLs via an array
53
+ of arguments (usually symbols and records). If a developer passes a
54
+ user input array, strings can result in unwanted route helper calls.
55
+
56
+ CVE-2021-22885
57
+
58
+ *Gannon McGibbon*
59
+
60
+ ## Rails 6.1.3.1 (March 26, 2021) ##
61
+
62
+ * No changes.
63
+
64
+
65
+ ## Rails 6.1.3 (February 17, 2021) ##
66
+
67
+ * Re-define routes when not set correctly via inheritance.
68
+
69
+ *John Hawthorn*
70
+
71
+
72
+ ## Rails 6.1.2.1 (February 10, 2021) ##
73
+
74
+ * Prevent open redirect when allowed host starts with a dot
75
+
76
+ [CVE-2021-22881]
77
+
78
+ Thanks to @tktech (https://hackerone.com/tktech) for reporting this
79
+ issue and the patch!
80
+
81
+ *Aaron Patterson*
82
+
83
+
1
84
  ## Rails 6.1.2 (February 09, 2021) ##
2
85
 
3
86
  * Fix error in `ActionController::LogSubscriber` that would happen when throwing inside a controller action.
@@ -7,11 +7,27 @@ module AbstractController
7
7
  Module.new do
8
8
  define_method(:inherited) do |klass|
9
9
  super(klass)
10
- if namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
10
+
11
+ namespace = klass.module_parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
12
+ actual_routes = namespace ? namespace.railtie_routes_url_helpers._routes : routes
13
+
14
+ if namespace
11
15
  klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
12
16
  else
13
17
  klass.include(routes.url_helpers(include_path_helpers))
14
18
  end
19
+
20
+ # In the case that we have ex.
21
+ # class A::Foo < ApplicationController
22
+ # class Bar < A::Foo
23
+ # We will need to redefine _routes because it will not be correct
24
+ # via inheritance.
25
+ unless klass._routes.equal?(actual_routes)
26
+ klass.redefine_singleton_method(:_routes) { actual_routes }
27
+ klass.include(Module.new do
28
+ define_method(:_routes) { @_routes || actual_routes }
29
+ end)
30
+ end
15
31
  end
16
32
  end
17
33
  end
@@ -44,7 +44,7 @@ module ActionController
44
44
  # template digest from the ETag.
45
45
  def pick_template_for_etag(options)
46
46
  unless options[:template] == false
47
- options[:template] || "#{controller_path}/#{action_name}"
47
+ options[:template] || lookup_context.find_all(action_name, _prefixes).first&.virtual_path
48
48
  end
49
49
  end
50
50
 
@@ -407,7 +407,7 @@ module ActionController
407
407
  module Token
408
408
  TOKEN_KEY = "token="
409
409
  TOKEN_REGEX = /^(Token|Bearer)\s+/
410
- AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
410
+ AUTHN_PAIR_DELIMITERS = /(?:,|;|\t)/
411
411
  extend self
412
412
 
413
413
  module ControllerMethods
@@ -127,6 +127,11 @@ module ActionController
127
127
  class Buffer < ActionDispatch::Response::Buffer #:nodoc:
128
128
  include MonitorMixin
129
129
 
130
+ class << self
131
+ attr_accessor :queue_size
132
+ end
133
+ @queue_size = 10
134
+
130
135
  # Ignore that the client has disconnected.
131
136
  #
132
137
  # If this value is `true`, calling `write` after the client
@@ -136,7 +141,7 @@ module ActionController
136
141
  attr_accessor :ignore_disconnect
137
142
 
138
143
  def initialize(response)
139
- super(response, SizedQueue.new(10))
144
+ super(response, build_queue(self.class.queue_size))
140
145
  @error_callback = lambda { true }
141
146
  @cv = new_cond
142
147
  @aborted = false
@@ -214,6 +219,10 @@ module ActionController
214
219
  yield str
215
220
  end
216
221
  end
222
+
223
+ def build_queue(queue_size)
224
+ queue_size ? SizedQueue.new(queue_size) : Queue.new
225
+ end
217
226
  end
218
227
 
219
228
  class Response < ActionDispatch::Response #:nodoc: all
@@ -281,7 +281,10 @@ module ActionController
281
281
  return false unless request.has_content_type?
282
282
 
283
283
  ref = request.content_mime_type.ref
284
+
284
285
  _wrapper_formats.include?(ref) && _wrapper_key && !request.parameters.key?(_wrapper_key)
286
+ rescue ActionDispatch::Http::Parameters::ParseError
287
+ false
285
288
  end
286
289
 
287
290
  def _perform_parameter_wrapping
@@ -295,8 +298,6 @@ module ActionController
295
298
 
296
299
  # This will display the wrapped hash in the log file.
297
300
  request.filtered_parameters.merge! wrapped_filtered_hash
298
- rescue ActionDispatch::Http::Parameters::ParseError
299
- # swallow parse error exception
300
301
  end
301
302
  end
302
303
  end
@@ -84,7 +84,7 @@ module ActionController
84
84
  #
85
85
  # If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
86
86
  #
87
- # If an object responding to `render_in` is passed, `render_in` is called on the object,
87
+ # If an object responding to +render_in+ is passed, +render_in+ is called on the object,
88
88
  # passing in the current view context.
89
89
  #
90
90
  # Otherwise, a partial is rendered using the second parameter as the locals hash.
@@ -24,6 +24,9 @@ module ActionController
24
24
  def new_controller_thread # :nodoc:
25
25
  yield
26
26
  end
27
+
28
+ # Avoid a deadlock from the queue filling up
29
+ Buffer.queue_size = nil
27
30
  end
28
31
 
29
32
  # ActionController::TestCase will be deprecated and moved to a gem in the future.
@@ -195,31 +195,30 @@ module ActionDispatch
195
195
 
196
196
  control.merge! cache_control
197
197
 
198
+ options = []
199
+
198
200
  if control[:no_store]
199
- self._cache_control = NO_STORE
201
+ options << PRIVATE if control[:private]
202
+ options << NO_STORE
200
203
  elsif control[:no_cache]
201
- options = []
202
204
  options << PUBLIC if control[:public]
203
205
  options << NO_CACHE
204
206
  options.concat(control[:extras]) if control[:extras]
205
-
206
- self._cache_control = options.join(", ")
207
207
  else
208
208
  extras = control[:extras]
209
209
  max_age = control[:max_age]
210
210
  stale_while_revalidate = control[:stale_while_revalidate]
211
211
  stale_if_error = control[:stale_if_error]
212
212
 
213
- options = []
214
213
  options << "max-age=#{max_age.to_i}" if max_age
215
214
  options << (control[:public] ? PUBLIC : PRIVATE)
216
215
  options << MUST_REVALIDATE if control[:must_revalidate]
217
216
  options << "stale-while-revalidate=#{stale_while_revalidate.to_i}" if stale_while_revalidate
218
217
  options << "stale-if-error=#{stale_if_error.to_i}" if stale_if_error
219
218
  options.concat(extras) if extras
220
-
221
- self._cache_control = options.join(", ")
222
219
  end
220
+
221
+ self._cache_control = options.join(", ")
223
222
  end
224
223
  end
225
224
  end
@@ -229,7 +229,7 @@ module Mime
229
229
  MIME_PARAMETER_KEY = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
230
230
  MIME_PARAMETER_VALUE = "#{Regexp.escape('"')}?[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}#{Regexp.escape('"')}?"
231
231
  MIME_PARAMETER = "\s*\;\s*#{MIME_PARAMETER_KEY}(?:\=#{MIME_PARAMETER_VALUE})?"
232
- MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?:\s*#{MIME_PARAMETER}\s*)*)\z/
232
+ MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>\s*#{MIME_PARAMETER}\s*)*)\z/
233
233
 
234
234
  class InvalidMimeType < StandardError; end
235
235
 
@@ -330,7 +330,7 @@ module Mime
330
330
  end
331
331
 
332
332
  # ALL isn't a real MIME type, so we don't register it for lookup with the
333
- # other concrete types. It's a wildcard match that we use for `respond_to`
333
+ # other concrete types. It's a wildcard match that we use for +respond_to+
334
334
  # negotiation internals.
335
335
  ALL = AllType.instance
336
336
 
@@ -103,7 +103,7 @@ module ActionDispatch
103
103
  parameterized_parts = recall.merge(options)
104
104
 
105
105
  keys_to_keep = route.parts.reverse_each.drop_while { |part|
106
- !(options.key?(part) || route.scope_options.key?(part)) || (options[part] || recall[part]).nil?
106
+ !(options.key?(part) || route.scope_options.key?(part)) || (options[part].nil? && recall[part].nil?)
107
107
  } | route.required_parts
108
108
 
109
109
  parameterized_parts.delete_if do |bad_key, _|
@@ -118,7 +118,7 @@ module ActionDispatch
118
118
  end
119
119
  end
120
120
 
121
- parameterized_parts.keep_if { |_, v| v }
121
+ parameterized_parts.compact!
122
122
  parameterized_parts
123
123
  end
124
124
 
@@ -40,7 +40,7 @@ module ActionDispatch
40
40
  @parameters.each do |index|
41
41
  param = parts[index]
42
42
  value = hash[param.name]
43
- return "" unless value
43
+ return "" if value.nil?
44
44
  parts[index] = param.escape value
45
45
  end
46
46
 
@@ -13,7 +13,7 @@ module ActionDispatch
13
13
  #
14
14
  # When a request comes to an unauthorized host, the +response_app+
15
15
  # application will be executed and rendered. If no +response_app+ is given, a
16
- # default one will run, which responds with +403 Forbidden+.
16
+ # default one will run, which responds with <tt>403 Forbidden</tt>.
17
17
  class HostAuthorization
18
18
  class Permissions # :nodoc:
19
19
  def initialize(hosts)
@@ -53,7 +53,7 @@ module ActionDispatch
53
53
  if host.start_with?(".")
54
54
  /\A(.+\.)?#{Regexp.escape(host[1..-1])}\z/i
55
55
  else
56
- /\A#{host}\z/i
56
+ /\A#{Regexp.escape host}\z/i
57
57
  end
58
58
  end
59
59
  end
@@ -103,11 +103,20 @@ module ActionDispatch
103
103
 
104
104
  private
105
105
  def authorized?(request)
106
- origin_host = request.get_header("HTTP_HOST").to_s.sub(/:\d+\z/, "")
107
- forwarded_host = request.x_forwarded_host.to_s.split(/,\s?/).last.to_s.sub(/:\d+\z/, "")
108
-
109
- @permissions.allows?(origin_host) &&
110
- (forwarded_host.blank? || @permissions.allows?(forwarded_host))
106
+ valid_host = /
107
+ \A
108
+ (?<host>[a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9.:]+\])
109
+ (:\d+)?
110
+ \z
111
+ /x
112
+
113
+ origin_host = valid_host.match(
114
+ request.get_header("HTTP_HOST").to_s.downcase)
115
+ forwarded_host = valid_host.match(
116
+ request.x_forwarded_host.to_s.split(/,\s?/).last)
117
+
118
+ origin_host && @permissions.allows?(origin_host[:host]) && (
119
+ forwarded_host.nil? || @permissions.allows?(forwarded_host[:host]))
111
120
  end
112
121
 
113
122
  def excluded?(request)
@@ -43,7 +43,7 @@ module ActionDispatch
43
43
  end
44
44
 
45
45
  # This class is used to instrument the execution of a single middleware.
46
- # It proxies the `call` method transparently and instruments the method
46
+ # It proxies the +call+ method transparently and instruments the method
47
47
  # call.
48
48
  class InstrumentationProxy
49
49
  EVENT_NAME = "process_middleware.action_dispatch"
@@ -32,12 +32,12 @@ module ActionDispatch
32
32
  #
33
33
  # Precompressed versions of these files are checked first. Brotli (.br)
34
34
  # and gzip (.gz) files are supported. If +path+.br exists, this
35
- # endpoint returns that file with a +Content-Encoding: br+ header.
35
+ # endpoint returns that file with a <tt>Content-Encoding: br</tt> header.
36
36
  #
37
37
  # If no matching file is found, this endpoint responds 404 Not Found.
38
38
  #
39
39
  # Pass the +root+ directory to search for matching files, an optional
40
- # +index: "index"+ to change the default +path+/index.html, and optional
40
+ # <tt>index: "index"</tt> to change the default +path+/index.html, and optional
41
41
  # additional response headers.
42
42
  class FileHandler
43
43
  # Accept-Encoding value -> file extension
@@ -6,6 +6,7 @@
6
6
  <%= @exception.message %>
7
7
  <% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
8
8
  To resolve this issue run: bin/rails active_storage:install
9
+ <% end %>
9
10
  <% if defined?(ActionMailbox) && @exception.message.match?(%r{#{ActionMailbox::InboundEmail.table_name}}) %>
10
11
  To resolve this issue run: bin/rails action_mailbox:install
11
12
  <% end %>
@@ -287,10 +287,12 @@ module ActionDispatch
287
287
 
288
288
  args = []
289
289
 
290
- route = record_list.map { |parent|
290
+ route = record_list.map do |parent|
291
291
  case parent
292
- when Symbol, String
292
+ when Symbol
293
293
  parent.to_s
294
+ when String
295
+ raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
294
296
  when Class
295
297
  args << parent
296
298
  parent.model_name.singular_route_key
@@ -298,12 +300,14 @@ module ActionDispatch
298
300
  args << parent.to_model
299
301
  parent.to_model.model_name.singular_route_key
300
302
  end
301
- }
303
+ end
302
304
 
303
305
  route <<
304
306
  case record
305
- when Symbol, String
307
+ when Symbol
306
308
  record.to_s
309
+ when String
310
+ raise(ArgumentError, "Please use symbols for polymorphic route arguments.")
307
311
  when Class
308
312
  @key_strategy.call record.model_name
309
313
  else
@@ -164,7 +164,7 @@ module ActionDispatch
164
164
  # "http://#{request.host_with_port}/#{path}"
165
165
  # }
166
166
  #
167
- # Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass
167
+ # Note that the <tt>do end</tt> syntax for the redirect block wouldn't work, as Ruby would pass
168
168
  # the block to +get+ instead of +redirect+. Use <tt>{ ... }</tt> instead.
169
169
  #
170
170
  # The options version of redirect allows you to supply only the parts of the URL which need
@@ -199,11 +199,11 @@ module ActionDispatch
199
199
  # merged into the Rack env hash.
200
200
  # - +env+: Additional env to pass, as a Hash. The headers will be
201
201
  # merged into the Rack env hash.
202
- # - +xhr+: Set to `true` if you want to make and Ajax request.
202
+ # - +xhr+: Set to +true+ if you want to make and Ajax request.
203
203
  # Adds request headers characteristic of XMLHttpRequest e.g. HTTP_X_REQUESTED_WITH.
204
204
  # The headers will be merged into the Rack env hash.
205
205
  # - +as+: Used for encoding the request with different content type.
206
- # Supports `:json` by default and will set the appropriate request headers.
206
+ # Supports +:json+ by default and will set the appropriate request headers.
207
207
  # The headers will be merged into the Rack env hash.
208
208
  #
209
209
  # This method is rarely used directly. Use +#get+, +#post+, or other standard
@@ -9,7 +9,7 @@ module ActionPack
9
9
  module VERSION
10
10
  MAJOR = 6
11
11
  MINOR = 1
12
- TINY = 2
12
+ TINY = 4
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.2
4
+ version: 6.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 6.1.2
19
+ version: 6.1.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 6.1.2
26
+ version: 6.1.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,28 +98,28 @@ dependencies:
98
98
  requirements:
99
99
  - - '='
100
100
  - !ruby/object:Gem::Version
101
- version: 6.1.2
101
+ version: 6.1.4
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - '='
107
107
  - !ruby/object:Gem::Version
108
- version: 6.1.2
108
+ version: 6.1.4
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: activemodel
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - '='
114
114
  - !ruby/object:Gem::Version
115
- version: 6.1.2
115
+ version: 6.1.4
116
116
  type: :development
117
117
  prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - '='
121
121
  - !ruby/object:Gem::Version
122
- version: 6.1.2
122
+ version: 6.1.4
123
123
  description: Web apps on Rails. Simple, battle-tested conventions for building and
124
124
  testing MVC web applications. Works with any Rack-compatible server.
125
125
  email: david@loudthinking.com
@@ -309,11 +309,11 @@ licenses:
309
309
  - MIT
310
310
  metadata:
311
311
  bug_tracker_uri: https://github.com/rails/rails/issues
312
- changelog_uri: https://github.com/rails/rails/blob/v6.1.2/actionpack/CHANGELOG.md
313
- documentation_uri: https://api.rubyonrails.org/v6.1.2/
312
+ changelog_uri: https://github.com/rails/rails/blob/v6.1.4/actionpack/CHANGELOG.md
313
+ documentation_uri: https://api.rubyonrails.org/v6.1.4/
314
314
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
315
- source_code_uri: https://github.com/rails/rails/tree/v6.1.2/actionpack
316
- post_install_message:
315
+ source_code_uri: https://github.com/rails/rails/tree/v6.1.4/actionpack
316
+ post_install_message:
317
317
  rdoc_options: []
318
318
  require_paths:
319
319
  - lib
@@ -329,8 +329,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
329
329
  version: '0'
330
330
  requirements:
331
331
  - none
332
- rubygems_version: 3.2.3
333
- signing_key:
332
+ rubygems_version: 3.1.2
333
+ signing_key:
334
334
  specification_version: 4
335
335
  summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
336
336
  test_files: []