Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: ruby-r...@packages.debian.org
Control: affects -1 + src:ruby-rack

Please see these changes for ruby-rack (I have not uploaded yet) is ok.

[ Reason ]
It fixes two CVEs (though it includes some other bug fixes too)

[ Impact ]
Some of the changes included in this release are already included in the debian package as patches, this just reduces maintenance effort.

[ Tests ]
Upstream testsuite passes, gitlab is already using the 2.2.6.4 version.

[ Risks ]
If this is not unblocked, two CVEs would have to be backported to 2.2.4


[ Checklist ]
 [x] all changes are documented in the d/changelog
 [x] I reviewed all changes and I approve them
 [x] attach debdiff against the package in testing

[ Other info ]

unblock ruby-rack/2.2.6.4-1


diff -Nru ruby-rack-2.2.4/CHANGELOG.md ruby-rack-2.2.6.4/CHANGELOG.md
--- ruby-rack-2.2.4/CHANGELOG.md	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/CHANGELOG.md	2023-03-13 23:37:51.000000000 +0530
@@ -2,6 +2,33 @@
 
 All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/).
 
+## [2.2.6.4] - 2023-03-13
+
+- [CVE-2023-27539] Avoid ReDoS in header parsing
+
+## [2.2.6.3] - 2023-03-02
+
+- [CVE-2023-27530] Introduce multipart_total_part_limit to limit total parts
+
+## [2.2.6.2] - 2022-01-17
+
+- [CVE-2022-44570] Fix ReDoS in Rack::Utils.get_byte_ranges
+
+## [2.2.6.1] - 2022-01-17
+
+- [CVE-2022-44571] Fix ReDoS vulnerability in multipart parser
+- [CVE-2022-44572] Forbid control characters in attributes (also ReDoS)
+
+## [2.2.6] - 2022-01-17
+
+- Extend `Rack::MethodOverride` to handle `QueryParser::ParamsTooDeepError` error. ([#2011](https://github.com/rack/rack/pull/2011), [@byroot](https://github.com/byroot))
+
+## [2.2.5] - 2022-12-27
+
+### Fixed
+
+- `Rack::URLMap` uses non-deprecated form of `Regexp.new`. ([#1998](https://github.com/rack/rack/pull/1998), [@weizheheng](https://github.com/weizheheng))
+
 ## [2.2.4] - 2022-06-30
 
 - Better support for lower case headers in `Rack::ETag` middleware. ([#1919](https://github.com/rack/rack/pull/1919), [@ioquatix](https://github.com/ioquatix))
diff -Nru ruby-rack-2.2.4/debian/changelog ruby-rack-2.2.6.4/debian/changelog
--- ruby-rack-2.2.4/debian/changelog	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/changelog	2023-03-24 01:32:43.000000000 +0530
@@ -1,3 +1,10 @@
+ruby-rack (2.2.6.4-1) unstable; urgency=medium
+
+  * Team Upload
+  * New upstream version 2.2.6.4 (Fixes: CVE-2023-27530, CVE-2023-27539)
+
+ -- Pirate Praveen <prav...@debian.org>  Fri, 24 Mar 2023 01:32:43 +0530
+
 ruby-rack (2.2.4-3) unstable; urgency=high
 
   * Team upload
diff -Nru ruby-rack-2.2.4/debian/patches/Fix-ReDoS-in-Rack-Utils.get_byte_ranges.patch ruby-rack-2.2.6.4/debian/patches/Fix-ReDoS-in-Rack-Utils.get_byte_ranges.patch
--- ruby-rack-2.2.4/debian/patches/Fix-ReDoS-in-Rack-Utils.get_byte_ranges.patch	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/patches/Fix-ReDoS-in-Rack-Utils.get_byte_ranges.patch	1970-01-01 05:30:00.000000000 +0530
@@ -1,26 +0,0 @@
---- a/lib/rack/utils.rb
-+++ b/lib/rack/utils.rb
-@@ -348,17 +348,18 @@
-       return nil unless http_range && http_range =~ /bytes=([^;]+)/
-       ranges = []
-       $1.split(/,\s*/).each do |range_spec|
--        return nil  unless range_spec =~ /(\d*)-(\d*)/
--        r0, r1 = $1, $2
--        if r0.empty?
--          return nil  if r1.empty?
-+        return nil unless range_spec.include?('-')
-+        range = range_spec.split('-')
-+        r0, r1 = range[0], range[1]
-+        if r0.nil? || r0.empty?
-+          return nil if r1.nil?
-           # suffix-byte-range-spec, represents trailing suffix of file
-           r0 = size - r1.to_i
-           r0 = 0  if r0 < 0
-           r1 = size - 1
-         else
-           r0 = r0.to_i
--          if r1.empty?
-+          if r1.nil?
-             r1 = size - 1
-           else
-             r1 = r1.to_i
diff -Nru ruby-rack-2.2.4/debian/patches/Fix-ReDoS-vulnerability-in-multipart-parser.patch ruby-rack-2.2.6.4/debian/patches/Fix-ReDoS-vulnerability-in-multipart-parser.patch
--- ruby-rack-2.2.4/debian/patches/Fix-ReDoS-vulnerability-in-multipart-parser.patch	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/patches/Fix-ReDoS-vulnerability-in-multipart-parser.patch	1970-01-01 05:30:00.000000000 +0530
@@ -1,11 +0,0 @@
---- a/lib/rack/multipart.rb
-+++ b/lib/rack/multipart.rb
-@@ -18,7 +18,7 @@
-     VALUE = /"(?:\\"|[^"])*"|#{TOKEN}/
-     BROKEN = /^#{CONDISP}.*;\s*filename=(#{VALUE})/i
-     MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni
--    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*;\s*name=(#{VALUE})/ni
-+    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:[^:]*;\s*name=(#{VALUE})/ni
-     MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
-     # Updated definitions from RFC 2231
-     ATTRIBUTE_CHAR = %r{[^ \t\v\n\r)(><@,;:\\"/\[\]?='*%]}
diff -Nru ruby-rack-2.2.4/debian/patches/Forbid-control-characters-in-attributes.patch ruby-rack-2.2.6.4/debian/patches/Forbid-control-characters-in-attributes.patch
--- ruby-rack-2.2.4/debian/patches/Forbid-control-characters-in-attributes.patch	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/patches/Forbid-control-characters-in-attributes.patch	1970-01-01 05:30:00.000000000 +0530
@@ -1,13 +0,0 @@
-This patch restricts the characters accepted in ATTRIBUTE_CHAR,
-forbidding control characters and fixing a ReDOS vulnerability.
---- a/lib/rack/multipart.rb
-+++ b/lib/rack/multipart.rb
-@@ -21,7 +21,7 @@
-     MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:[^:]*;\s*name=(#{VALUE})/ni
-     MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
-     # Updated definitions from RFC 2231
--    ATTRIBUTE_CHAR = %r{[^ \t\v\n\r)(><@,;:\\"/\[\]?='*%]}
-+    ATTRIBUTE_CHAR = %r{[^ \x00-\x1f\x7f)(><@,;:\\"/\[\]?='*%]}
-     ATTRIBUTE = /#{ATTRIBUTE_CHAR}+/
-     SECTION = /\*[0-9]+/
-     REGULAR_PARAMETER_NAME = /#{ATTRIBUTE}#{SECTION}?/
diff -Nru ruby-rack-2.2.4/debian/patches/Remove-leading-dot-to-fix-compatibility-with-latest-cgi-gem.patch ruby-rack-2.2.6.4/debian/patches/Remove-leading-dot-to-fix-compatibility-with-latest-cgi-gem.patch
--- ruby-rack-2.2.4/debian/patches/Remove-leading-dot-to-fix-compatibility-with-latest-cgi-gem.patch	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/patches/Remove-leading-dot-to-fix-compatibility-with-latest-cgi-gem.patch	1970-01-01 05:30:00.000000000 +0530
@@ -1,31 +0,0 @@
---- a/test/spec_mock.rb
-+++ b/test/spec_mock.rb
-@@ -19,8 +19,8 @@
-     req.GET["status"] || 200,
-     "Content-Type" => "text/yaml"
-   )
--  response.set_cookie("session_test", { value: "session_test", domain: ".test.com", path: "/" })
--  response.set_cookie("secure_test", { value: "secure_test", domain: ".test.com",  path: "/", secure: true })
-+  response.set_cookie("session_test", { value: "session_test", domain: "test.com", path: "/" })
-+  response.set_cookie("secure_test", { value: "secure_test", domain: "test.com",  path: "/", secure: true })
-   response.set_cookie("persistent_test", { value: "persistent_test", max_age: 15552000, path: "/" })
-   response.finish
- })
-@@ -293,7 +293,7 @@
-     res = Rack::MockRequest.new(app).get("")
-     session_cookie = res.cookie("session_test")
-     session_cookie.value[0].must_equal "session_test"
--    session_cookie.domain.must_equal ".test.com"
-+    session_cookie.domain.must_equal "test.com"
-     session_cookie.path.must_equal "/"
-     session_cookie.secure.must_equal false
-     session_cookie.expires.must_be_nil
-@@ -314,7 +314,7 @@
-     res = Rack::MockRequest.new(app).get("")
-     secure_cookie = res.cookie("secure_test")
-     secure_cookie.value[0].must_equal "secure_test"
--    secure_cookie.domain.must_equal ".test.com"
-+    secure_cookie.domain.must_equal "test.com"
-     secure_cookie.path.must_equal "/"
-     secure_cookie.secure.must_equal true
-     secure_cookie.expires.must_be_nil
diff -Nru ruby-rack-2.2.4/debian/patches/series ruby-rack-2.2.6.4/debian/patches/series
--- ruby-rack-2.2.4/debian/patches/series	2023-02-09 16:17:17.000000000 +0530
+++ ruby-rack-2.2.6.4/debian/patches/series	2023-03-24 01:32:43.000000000 +0530
@@ -1,7 +1,3 @@
 skip-random-failure.patch
 0002-Make-tests-pass-on-hosts-that-have-no-ipv4-connectiv.patch
 skip-unreadable-dir-test.patch
-Remove-leading-dot-to-fix-compatibility-with-latest-cgi-gem.patch
-Fix-ReDoS-in-Rack-Utils.get_byte_ranges.patch
-Fix-ReDoS-vulnerability-in-multipart-parser.patch
-Forbid-control-characters-in-attributes.patch
diff -Nru ruby-rack-2.2.4/.github/workflows/development.yml ruby-rack-2.2.6.4/.github/workflows/development.yml
--- ruby-rack-2.2.4/.github/workflows/development.yml	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/.github/workflows/development.yml	2023-03-13 23:37:51.000000000 +0530
@@ -8,7 +8,7 @@
       fail-fast: false
       matrix:
         os: [ubuntu-20.04]
-        ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0', 3.1]
+        ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2]
     runs-on: ${{matrix.os}}
     steps:
     - uses: actions/checkout@v2
@@ -29,7 +29,6 @@
 
     - name: Bundle install...
       run: |
-        gem update --system
         bundle config path vendor/bundle
         bundle install
 
diff -Nru ruby-rack-2.2.4/lib/rack/method_override.rb ruby-rack-2.2.6.4/lib/rack/method_override.rb
--- ruby-rack-2.2.4/lib/rack/method_override.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/method_override.rb	2023-03-13 23:37:51.000000000 +0530
@@ -43,7 +43,7 @@
 
     def method_override_param(req)
       req.POST[METHOD_OVERRIDE_PARAM_KEY]
-    rescue Utils::InvalidParameterError, Utils::ParameterTypeError
+    rescue Utils::InvalidParameterError, Utils::ParameterTypeError, QueryParser::ParamsTooDeepError
       req.get_header(RACK_ERRORS).puts "Invalid or incomplete POST params"
     rescue EOFError
       req.get_header(RACK_ERRORS).puts "Bad request content body"
diff -Nru ruby-rack-2.2.4/lib/rack/multipart/parser.rb ruby-rack-2.2.6.4/lib/rack/multipart/parser.rb
--- ruby-rack-2.2.4/lib/rack/multipart/parser.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/multipart/parser.rb	2023-03-13 23:37:51.000000000 +0530
@@ -5,6 +5,7 @@
 module Rack
   module Multipart
     class MultipartPartLimitError < Errno::EMFILE; end
+    class MultipartTotalPartLimitError < StandardError; end
 
     class Parser
       (require_relative '../core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
@@ -140,7 +141,7 @@
 
           @mime_parts[mime_index] = klass.new(body, head, filename, content_type, name)
 
-          check_open_files
+          check_part_limits
         end
 
         def on_mime_body(mime_index, content)
@@ -152,13 +153,23 @@
 
         private
 
-        def check_open_files
-          if Utils.multipart_part_limit > 0
-            if @open_files >= Utils.multipart_part_limit
+        def check_part_limits
+          file_limit = Utils.multipart_file_limit
+          part_limit = Utils.multipart_total_part_limit
+
+          if file_limit && file_limit > 0
+            if @open_files >= file_limit
               @mime_parts.each(&:close)
               raise MultipartPartLimitError, 'Maximum file multiparts in content reached'
             end
           end
+
+          if part_limit && part_limit > 0
+            if @mime_parts.size >= part_limit
+              @mime_parts.each(&:close)
+              raise MultipartTotalPartLimitError, 'Maximum total multiparts in content reached'
+            end
+          end
         end
       end
 
diff -Nru ruby-rack-2.2.4/lib/rack/multipart.rb ruby-rack-2.2.6.4/lib/rack/multipart.rb
--- ruby-rack-2.2.4/lib/rack/multipart.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/multipart.rb	2023-03-13 23:37:51.000000000 +0530
@@ -18,10 +18,10 @@
     VALUE = /"(?:\\"|[^"])*"|#{TOKEN}/
     BROKEN = /^#{CONDISP}.*;\s*filename=(#{VALUE})/i
     MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni
-    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*;\s*name=(#{VALUE})/ni
+    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:[^:]*;\s*name=(#{VALUE})/ni
     MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
     # Updated definitions from RFC 2231
-    ATTRIBUTE_CHAR = %r{[^ \t\v\n\r)(><@,;:\\"/\[\]?='*%]}
+    ATTRIBUTE_CHAR = %r{[^ \x00-\x1f\x7f)(><@,;:\\"/\[\]?='*%]}
     ATTRIBUTE = /#{ATTRIBUTE_CHAR}+/
     SECTION = /\*[0-9]+/
     REGULAR_PARAMETER_NAME = /#{ATTRIBUTE}#{SECTION}?/
diff -Nru ruby-rack-2.2.4/lib/rack/request.rb ruby-rack-2.2.6.4/lib/rack/request.rb
--- ruby-rack-2.2.4/lib/rack/request.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/request.rb	2023-03-13 23:37:51.000000000 +0530
@@ -572,8 +572,8 @@
       end
 
       def parse_http_accept_header(header)
-        header.to_s.split(/\s*,\s*/).map do |part|
-          attribute, parameters = part.split(/\s*;\s*/, 2)
+        header.to_s.split(",").each(&:strip!).map do |part|
+          attribute, parameters = part.split(";", 2).each(&:strip!)
           quality = 1.0
           if parameters and /\Aq=([\d.]+)/ =~ parameters
             quality = $1.to_f
diff -Nru ruby-rack-2.2.4/lib/rack/urlmap.rb ruby-rack-2.2.6.4/lib/rack/urlmap.rb
--- ruby-rack-2.2.4/lib/rack/urlmap.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/urlmap.rb	2023-03-13 23:37:51.000000000 +0530
@@ -35,7 +35,7 @@
         end
 
         location = location.chomp('/')
-        match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
+        match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", Regexp::NOENCODING)
 
         [host, location, match, app]
       }.sort_by do |(host, location, _, _)|
diff -Nru ruby-rack-2.2.4/lib/rack/utils.rb ruby-rack-2.2.6.4/lib/rack/utils.rb
--- ruby-rack-2.2.4/lib/rack/utils.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/utils.rb	2023-03-13 23:37:51.000000000 +0530
@@ -58,13 +58,24 @@
     end
 
     class << self
-      attr_accessor :multipart_part_limit
+      attr_accessor :multipart_total_part_limit
+
+      attr_accessor :multipart_file_limit
+
+      # multipart_part_limit is the original name of multipart_file_limit, but
+      # the limit only counts parts with filenames.
+      alias multipart_part_limit multipart_file_limit
+      alias multipart_part_limit= multipart_file_limit=
     end
 
-    # The maximum number of parts a request can contain. Accepting too many part
-    # can lead to the server running out of file handles.
+    # The maximum number of file parts a request can contain. Accepting too
+    # many parts can lead to the server running out of file handles.
     # Set to `0` for no limit.
-    self.multipart_part_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || 128).to_i
+    self.multipart_file_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || ENV['RACK_MULTIPART_FILE_LIMIT'] || 128).to_i
+
+    # The maximum total number of parts a request can contain. Accepting too
+    # many can lead to excessive memory use and parsing time.
+    self.multipart_total_part_limit = (ENV['RACK_MULTIPART_TOTAL_PART_LIMIT'] || 4096).to_i
 
     def self.param_depth_limit
       default_query_parser.param_depth_limit
@@ -348,17 +359,18 @@
       return nil unless http_range && http_range =~ /bytes=([^;]+)/
       ranges = []
       $1.split(/,\s*/).each do |range_spec|
-        return nil  unless range_spec =~ /(\d*)-(\d*)/
-        r0, r1 = $1, $2
-        if r0.empty?
-          return nil  if r1.empty?
+        return nil unless range_spec.include?('-')
+        range = range_spec.split('-')
+        r0, r1 = range[0], range[1]
+        if r0.nil? || r0.empty?
+          return nil if r1.nil?
           # suffix-byte-range-spec, represents trailing suffix of file
           r0 = size - r1.to_i
           r0 = 0  if r0 < 0
           r1 = size - 1
         else
           r0 = r0.to_i
-          if r1.empty?
+          if r1.nil?
             r1 = size - 1
           else
             r1 = r1.to_i
diff -Nru ruby-rack-2.2.4/lib/rack/version.rb ruby-rack-2.2.6.4/lib/rack/version.rb
--- ruby-rack-2.2.4/lib/rack/version.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/lib/rack/version.rb	2023-03-13 23:37:51.000000000 +0530
@@ -20,7 +20,7 @@
     VERSION.join(".")
   end
 
-  RELEASE = "2.2.4"
+  RELEASE = "2.2.6.4"
 
   # Return the Rack release as a dotted string.
   def self.release
diff -Nru ruby-rack-2.2.4/README.rdoc ruby-rack-2.2.6.4/README.rdoc
--- ruby-rack-2.2.4/README.rdoc	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/README.rdoc	2023-03-13 23:37:51.000000000 +0530
@@ -202,16 +202,30 @@
 
 Defaults to 100.
 
-=== multipart_part_limit
+=== multipart_file_limit
 
-The maximum number of parts a request can contain.
+The maximum number of parts with a filename a request can contain.
 Accepting too many part can lead to the server running out of file handles.
 
 The default is 128, which means that a single request can't upload more than 128 files at once.
 
 Set to 0 for no limit.
 
-Can also be set via the +RACK_MULTIPART_PART_LIMIT+ environment variable.
+Can also be set via the +RACK_MULTIPART_FILE_LIMIT+ environment variable.
+
+(This is also aliased as +multipart_part_limit+ and +RACK_MULTIPART_PART_LIMIT+ for compatibility)
+
+=== multipart_total_part_limit
+
+The maximum total number of parts a request can contain of any type, including
+both file and non-file form fields.
+
+The default is 4096, which means that a single request can't contain more than
+4096 parts.
+
+Set to 0 for no limit.
+
+Can also be set via the +RACK_MULTIPART_TOTAL_PART_LIMIT+ environment variable.
 
 == Changelog
 
diff -Nru ruby-rack-2.2.4/test/spec_method_override.rb ruby-rack-2.2.6.4/test/spec_method_override.rb
--- ruby-rack-2.2.4/test/spec_method_override.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/test/spec_method_override.rb	2023-03-13 23:37:51.000000000 +0530
@@ -100,6 +100,13 @@
     env[Rack::RACK_ERRORS].read.must_match /Bad request content body/
   end
 
+  it "not modify REQUEST_METHOD for POST requests when the params are unparseable because too deep" do
+    env = Rack::MockRequest.env_for("/", method: "POST", input: ("[a]" * 36) + "=1")
+    app.call env
+
+    env["REQUEST_METHOD"].must_equal "POST"
+  end
+
   it "not modify REQUEST_METHOD for POST requests when the params are unparseable" do
     env = Rack::MockRequest.env_for("/", method: "POST", input: "(%bad-params%)")
     app.call env
diff -Nru ruby-rack-2.2.4/test/spec_mock.rb ruby-rack-2.2.6.4/test/spec_mock.rb
--- ruby-rack-2.2.4/test/spec_mock.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/test/spec_mock.rb	2023-03-13 23:37:51.000000000 +0530
@@ -19,8 +19,8 @@
     req.GET["status"] || 200,
     "Content-Type" => "text/yaml"
   )
-  response.set_cookie("session_test", { value: "session_test", domain: ".test.com", path: "/" })
-  response.set_cookie("secure_test", { value: "secure_test", domain: ".test.com",  path: "/", secure: true })
+  response.set_cookie("session_test", { value: "session_test", domain: "test.com", path: "/" })
+  response.set_cookie("secure_test", { value: "secure_test", domain: "test.com",  path: "/", secure: true })
   response.set_cookie("persistent_test", { value: "persistent_test", max_age: 15552000, path: "/" })
   response.finish
 })
@@ -293,7 +293,7 @@
     res = Rack::MockRequest.new(app).get("")
     session_cookie = res.cookie("session_test")
     session_cookie.value[0].must_equal "session_test"
-    session_cookie.domain.must_equal ".test.com"
+    session_cookie.domain.must_equal "test.com"
     session_cookie.path.must_equal "/"
     session_cookie.secure.must_equal false
     session_cookie.expires.must_be_nil
@@ -314,7 +314,7 @@
     res = Rack::MockRequest.new(app).get("")
     secure_cookie = res.cookie("secure_test")
     secure_cookie.value[0].must_equal "secure_test"
-    secure_cookie.domain.must_equal ".test.com"
+    secure_cookie.domain.must_equal "test.com"
     secure_cookie.path.must_equal "/"
     secure_cookie.secure.must_equal true
     secure_cookie.expires.must_be_nil
diff -Nru ruby-rack-2.2.4/test/spec_multipart.rb ruby-rack-2.2.6.4/test/spec_multipart.rb
--- ruby-rack-2.2.4/test/spec_multipart.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/test/spec_multipart.rb	2023-03-13 23:37:51.000000000 +0530
@@ -632,6 +632,18 @@
     end
   end
 
+  it "reach a multipart total limit" do
+    begin
+      previous_limit = Rack::Utils.multipart_total_part_limit
+      Rack::Utils.multipart_total_part_limit = 5
+
+      env = Rack::MockRequest.env_for '/', multipart_fixture(:three_files_three_fields)
+      lambda { Rack::Multipart.parse_multipart(env) }.must_raise Rack::Multipart::MultipartTotalPartLimitError
+    ensure
+      Rack::Utils.multipart_total_part_limit = previous_limit
+    end
+  end
+
   it "return nil if no UploadedFiles were used" do
     data = Rack::Multipart.build_multipart("people" => [{ "submit-name" => "Larry", "files" => "contents" }])
     data.must_be_nil
diff -Nru ruby-rack-2.2.4/test/spec_request.rb ruby-rack-2.2.6.4/test/spec_request.rb
--- ruby-rack-2.2.4/test/spec_request.rb	2022-07-01 03:48:29.000000000 +0530
+++ ruby-rack-2.2.6.4/test/spec_request.rb	2023-03-13 23:37:51.000000000 +0530
@@ -1000,7 +1000,7 @@
     f[:tempfile].size.must_equal 76
   end
 
-  it "MultipartPartLimitError when request has too many multipart parts if limit set" do
+  it "MultipartPartLimitError when request has too many multipart file parts if limit set" do
     begin
       data = 10000.times.map { "--AaB03x\r\nContent-Type: text/plain\r\nContent-Disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")
       data += "--AaB03x--\r"
@@ -1016,6 +1016,22 @@
     end
   end
 
+  it "MultipartPartLimitError when request has too many multipart total parts if limit set" do
+    begin
+      data = 10000.times.map { "--AaB03x\r\ncontent-type: text/plain\r\ncontent-disposition: attachment; name=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")
+      data += "--AaB03x--\r"
+
+      options = {
+        "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
+        "CONTENT_LENGTH" => data.length.to_s,
+        :input => StringIO.new(data)
+      }
+
+      request = make_request Rack::MockRequest.env_for("/", options)
+      lambda { request.POST }.must_raise Rack::Multipart::MultipartTotalPartLimitError
+    end
+  end
+
   it 'closes tempfiles it created in the case of too many created' do
     begin
       data = 10000.times.map { "--AaB03x\r\nContent-Type: text/plain\r\nContent-Disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n")

Reply via email to