From 8d1bf996e30897f740c54669d891eeda8036113d Mon Sep 17 00:00:00 2001 From: Hartley McGuire Date: Wed, 14 Jun 2023 03:24:10 +0000 Subject: [PATCH 1/8] Update CHANGELOG for 3.0.8 (#2086) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a7aa440..a9c901c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ 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/). +## [3.0.8] - 2023-06-14 + +- Fix some unused variable verbose warnings. ([#2084](https://github.com/rack/rack/pull/2084), [@jeremyevans], [@skipkayhil](https://github.com/skipkayhil)) + ## [3.0.7] - 2023-03-16 - Make query parameters without `=` have `nil` values. ([#2059](https://github.com/rack/rack/pull/2059), [@jeremyevans]) From c8b977f6c3a002b6e6f395ce8b5c14f21dad7f39 Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Tue, 30 Jan 2024 21:56:31 -0800 Subject: [PATCH 2/8] Fix content-length calcuation in Rack:Response#write (#2150) When `Rack::Response` is initialized with an Array, it incorrectly increments its internal `@length` value and emitted content-length header on every subsequent write. The more times `write` is called, the more the error accumulates. This commit fixes the accumulation bug, and fixes/adds specs to properly test the scenario where `write` is used multiple times. --- CHANGELOG.md | 6 ++++++ lib/rack/response.rb | 2 ++ test/spec_response.rb | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c901c0d..6e155c4dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ 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/). +## Unreleased + +### Changed + +- Fix incorrect content-length header that was emitted when `Rack::Response#write` was used in some situations. ([#2150](https://github.com/rack/rack/pull/2150), [@mattbrictson]) + ## [3.0.8] - 2023-06-14 - Fix some unused variable verbose warnings. ([#2084](https://github.com/rack/rack/pull/2084), [@jeremyevans], [@skipkayhil](https://github.com/skipkayhil)) diff --git a/lib/rack/response.rb b/lib/rack/response.rb index f24683bcb..b9b02c272 100644 --- a/lib/rack/response.rb +++ b/lib/rack/response.rb @@ -328,6 +328,8 @@ def buffered_body! @body.each do |part| @length += part.to_s.bytesize end + + @buffered = true elsif @body.respond_to?(:each) # Turn the user supplied body into a buffered array: body = @body diff --git a/test/spec_response.rb b/test/spec_response.rb index ef8aa481c..11e64d61f 100644 --- a/test/spec_response.rb +++ b/test/spec_response.rb @@ -412,7 +412,7 @@ def object_with_each.each status.must_equal 404 end - it "correctly updates content-type when writing when not initialized with body" do + it "correctly updates content-length when writing when initialized without body" do r = Rack::Response.new r.write('foo') r.write('bar') @@ -423,20 +423,39 @@ def object_with_each.each header['content-length'].must_equal '9' end - it "correctly updates content-type when writing when initialized with body" do + it "correctly updates content-length when writing when initialized with Array body" do + r = Rack::Response.new(["foo"]) + r.write('bar') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbaz" + header['content-length'].must_equal '9' + end + + it "correctly updates content-length when writing when initialized with String body" do + r = Rack::Response.new("foo") + r.write('bar') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbaz" + header['content-length'].must_equal '9' + end + + it "correctly updates content-length when writing when initialized with object body that responds to #each" do obj = Object.new def obj.each yield 'foo' yield 'bar' end - ["foobar", ["foo", "bar"], obj].each do - r = Rack::Response.new(["foo", "bar"]) - r.write('baz') - _, header, body = r.finish - str = "".dup; body.each { |part| str << part } - str.must_equal "foobarbaz" - header['content-length'].must_equal '9' - end + r = Rack::Response.new(obj) + r.write('baz') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbazbaz" + header['content-length'].must_equal '12' end it "doesn't return invalid responses" do From d3d415ed68fe9471f04bafe4a299eb099330fcb1 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 5 Jan 2024 09:02:30 +1300 Subject: [PATCH 3/8] Update Ruby versions for external tests: drop v2.7 and add v3.2 and v3.3. (#2143) --- .github/workflows/test-external.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-external.yaml b/.github/workflows/test-external.yaml index d55882cea..bcf7a6c72 100644 --- a/.github/workflows/test-external.yaml +++ b/.github/workflows/test-external.yaml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - ruby: ['2.7', '3.0', '3.1'] + ruby: ['3.0', '3.1', '3.2', '3.3'] runs-on: ${{matrix.os}} From 0b3f997e7bb14c1dc42130e1eb50e62797d8c039 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Wed, 31 Jan 2024 20:51:51 +1300 Subject: [PATCH 4/8] Bump patch version. --- CHANGELOG.md | 2 +- lib/rack/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e155c4dc..c1f38daf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. For info on ## Unreleased -### Changed +## [3.0.9] - 2024-01-31 - Fix incorrect content-length header that was emitted when `Rack::Response#write` was used in some situations. ([#2150](https://github.com/rack/rack/pull/2150), [@mattbrictson]) diff --git a/lib/rack/version.rb b/lib/rack/version.rb index e634f23ae..e2deadab2 100644 --- a/lib/rack/version.rb +++ b/lib/rack/version.rb @@ -25,7 +25,7 @@ def self.version VERSION end - RELEASE = "3.0.8" + RELEASE = "3.0.9" # Return the Rack release as a dotted string. def self.release From a227cd793778c7c3a827d32808058571569cda6f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 21 Feb 2024 11:05:06 -0800 Subject: [PATCH 5/8] Fixing ReDoS in header parsing Thanks svalkanov [CVE-2024-26146] --- lib/rack/utils.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 99d696dbf..62c2502cc 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -143,8 +143,8 @@ def build_nested_query(value, prefix = nil) end def q_values(q_value_header) - q_value_header.to_s.split(/\s*,\s*/).map do |part| - value, parameters = part.split(/\s*;\s*/, 2) + q_value_header.to_s.split(',').map do |part| + value, parameters = part.split(';', 2).map(&:strip) quality = 1.0 if parameters && (md = /\Aq=([\d.]+)/.match(parameters)) quality = md[1].to_f @@ -157,9 +157,10 @@ def forwarded_values(forwarded_header) return nil unless forwarded_header forwarded_header = forwarded_header.to_s.gsub("\n", ";") - forwarded_header.split(/\s*;\s*/).each_with_object({}) do |field, values| - field.split(/\s*,\s*/).each do |pair| - return nil unless pair =~ /\A\s*(by|for|host|proto)\s*=\s*"?([^"]+)"?\s*\Z/i + forwarded_header.split(';').each_with_object({}) do |field, values| + field.split(',').each do |pair| + pair = pair.split('=').map(&:strip).join('=') + return nil unless pair =~ /\A(by|for|host|proto)="?([^"]+)"?\Z/i (values[$1.downcase.to_sym] ||= []) << $2 end end From 4849132bef471adb21131980df745f4bb84de2d9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 13 Feb 2024 13:34:34 -0800 Subject: [PATCH 6/8] Return an empty array when ranges are too large If the sum of the requested ranges is larger than the file itself, return an empty array. In other words, refuse to respond with any bytes. [CVE-2024-26141] --- lib/rack/utils.rb | 3 +++ test/spec_utils.rb | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 62c2502cc..f91838b37 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -459,6 +459,9 @@ def get_byte_ranges(http_range, size) end ranges << (r0..r1) if r0 <= r1 end + + return [] if ranges.map(&:size).sum > size + ranges end diff --git a/test/spec_utils.rb b/test/spec_utils.rb index c4f9b27fa..2165c5a6a 100644 --- a/test/spec_utils.rb +++ b/test/spec_utils.rb @@ -716,6 +716,10 @@ def initialize(*) end describe Rack::Utils, "get_byte_ranges" do + it "returns an empty list if the sum of the ranges is too large" do + assert_equal [], Rack::Utils.byte_ranges({ "HTTP_RANGE" => "bytes=0-20,0-500" }, 500) + end + deprecated "pase simple byte ranges from env" do Rack::Utils.byte_ranges({ "HTTP_RANGE" => "bytes=123-456" }, 500).must_equal [(123..456)] end From 6efb2ceea003c4b195815a614e00438cbd543462 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 6 Dec 2023 18:32:19 +0100 Subject: [PATCH 7/8] Avoid 2nd degree polynomial regexp in MediaType --- lib/rack/media_type.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/rack/media_type.rb b/lib/rack/media_type.rb index ff3145deb..7fc1e39db 100644 --- a/lib/rack/media_type.rb +++ b/lib/rack/media_type.rb @@ -4,7 +4,7 @@ module Rack # Rack::MediaType parse media type and parameters out of content_type string class MediaType - SPLIT_PATTERN = %r{\s*[;,]\s*} + SPLIT_PATTERN = /[;,]/ class << self # The media type (type/subtype) portion of the CONTENT_TYPE header @@ -15,7 +15,11 @@ class << self # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 def type(content_type) return nil unless content_type - content_type.split(SPLIT_PATTERN, 2).first.tap(&:downcase!) + if type = content_type.split(SPLIT_PATTERN, 2).first + type.rstrip! + type.downcase! + type + end end # The media type parameters provided in CONTENT_TYPE as a Hash, or @@ -27,9 +31,10 @@ def params(content_type) return {} if content_type.nil? content_type.split(SPLIT_PATTERN)[1..-1].each_with_object({}) do |s, hsh| + s.strip! k, v = s.split('=', 2) - - hsh[k.tap(&:downcase!)] = strip_doublequotes(v) + k.downcase! + hsh[k] = strip_doublequotes(v) end end From a4bc5e0f41c750135969ceece8772ab112dc8f17 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 21 Feb 2024 11:23:31 -0800 Subject: [PATCH 8/8] bump version --- lib/rack/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rack/version.rb b/lib/rack/version.rb index e2deadab2..8817699e1 100644 --- a/lib/rack/version.rb +++ b/lib/rack/version.rb @@ -25,7 +25,7 @@ def self.version VERSION end - RELEASE = "3.0.9" + RELEASE = "3.0.9.1" # Return the Rack release as a dotted string. def self.release pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy