Bug#1033374: pre-unblock: ruby-rack/2.2.6.4-1
Control: tags -1 moreinfo
On 2023-03-24 01:50:25 +0530, Pirate Praveen wrote:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@packages.debian.org
> Usertags: unblock
> X-Debbugs-Cc: ruby-rack@packages.debian.org
> Control: affects -1 + src:ruby-rack
>
> Please see these changes for ruby-rack (I have not uploaded yet) is ok.
Please go ahead and let us know once the package is available in
unstable.
Cheers
>
> [ 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 <praveen@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")
--
Sebastian Ramacher
Reply to: