Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rubygem-rack for openSUSE:Factory checked in at 2025-05-22 16:56:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-rack (Old) and /work/SRC/openSUSE:Factory/.rubygem-rack.new.2732 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-rack" Thu May 22 16:56:19 2025 rev:32 rq:1278995 version:3.1.15 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-rack/rubygem-rack.changes 2025-03-11 20:47:12.862948187 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-rack.new.2732/rubygem-rack.changes 2025-05-22 16:56:38.873350361 +0200 @@ -1,0 +2,5 @@ +Wed May 21 08:44:20 UTC 2025 - Jay Michalska <jay.michal...@suse.com> + +- New upstream release 3.1.15, see bundled CHANGELOG.md + +------------------------------------------------------------------- Old: ---- rack-3.1.12.gem New: ---- rack-3.1.15.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-rack.spec ++++++ --- /var/tmp/diff_new_pack.SuLT0s/_old 2025-05-22 16:56:39.317369048 +0200 +++ /var/tmp/diff_new_pack.SuLT0s/_new 2025-05-22 16:56:39.317369048 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-rack -Version: 3.1.12 +Version: 3.1.15 Release: 0 %define mod_name rack %define mod_full_name %{mod_name}-%{version} ++++++ rack-3.1.12.gem -> rack-3.1.15.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2025-03-10 22:22:08.000000000 +0100 +++ new/CHANGELOG.md 1980-01-02 01:00:00.000000000 +0100 @@ -2,6 +2,20 @@ 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.1.15] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + +## [3.1.14] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + +## [3.1.13] - 2025-04-13 + +- Ensure `Rack::ETag` correctly updates response body. ([#2324](https://github.com/rack/rack/pull/2324), [@ioquatix]) + ## [3.1.12] - 2025-03-11 ### Security @@ -129,6 +143,21 @@ - In `Rack::Files`, ignore the `Range` header if served file is 0 bytes. ([#2159](https://github.com/rack/rack/pull/2159), [@zarqman]) +## [3.0.17] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + + +## [3.0.16] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + +## [3.0.15] - 2025-04-13 + +- Ensure `Rack::ETag` correctly updates response body. ([#2324](https://github.com/rack/rack/pull/2324), [@ioquatix]) + ## [3.0.14] - 2025-03-11 ### Security @@ -323,6 +352,16 @@ - Fix multipart filename generation for filenames that contain spaces. Encode spaces as "%20" instead of "+" which will be decoded properly by the multipart parser. ([#1736](https://github.com/rack/rack/pull/1645), [@muirdm](https://github.com/muirdm)) - `Rack::Request#scheme` returns `ws` or `wss` when one of the `X-Forwarded-Scheme` / `X-Forwarded-Proto` headers is set to `ws` or `wss`, respectively. ([#1730](https://github.com/rack/rack/issues/1730), [@erwanst](https://github.com/erwanst)) +## [2.2.15] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + +## [2.2.14] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + ## [2.2.13] - 2025-03-11 ### Security @@ -1104,3 +1143,4 @@ [@wjordan]: https://github.com/wjordan "Will Jordan" [@BlakeWilliams]: https://github.com/BlakeWilliams "Blake Williams" [@davidstosik]: https://github.com/davidstosik "David Stosik" +[@earlopain]: https://github.com/earlopain "Earlopain" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2025-03-10 22:22:08.000000000 +0100 +++ new/README.md 1980-01-02 01:00:00.000000000 +0100 @@ -183,6 +183,33 @@ Rack exposes several configuration parameters to control various features of the implementation. +### `RACK_QUERY_PARSER_BYTESIZE_LIMIT` + +This environment variable sets the default for the maximum query string bytesize +that `Rack::QueryParser` will attempt to parse. Attempts to use a query string +that exceeds this number of bytes will result in a +`Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is +provided, it must be an integer, or `Rack::QueryParser` will raise an exception. + +The default limit can be overridden on a per-`Rack::QueryParser` basis using +the `bytesize_limit` keyword argument when creating the `Rack::QueryParser`. + +### `RACK_QUERY_PARSER_PARAMS_LIMIT` + +This environment variable sets the default for the maximum number of query +parameters that `Rack::QueryParser` will attempt to parse. Attempts to use a +query string with more than this many query parameters will result in a +`Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is +provided, it must be an integer, or `Rack::QueryParser` will raise an exception. + +The default limit can be overridden on a per-`Rack::QueryParser` basis using +the `params_limit` keyword argument when creating the `Rack::QueryParser`. + +This is implemented by counting the number of parameter separators in the +query string, before attempting parsing, so if the same parameter key is +used multiple times in the query, each counts as a separate parameter for +this check. + ### `param_depth_limit` ```ruby Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rack/etag.rb new/lib/rack/etag.rb --- old/lib/rack/etag.rb 2025-03-10 22:22:08.000000000 +0100 +++ new/lib/rack/etag.rb 1980-01-02 01:00:00.000000000 +0100 @@ -32,6 +32,9 @@ body = body.to_ary digest = digest_body(body) headers[ETAG_STRING] = %(W/"#{digest}") if digest + + # Body was modified, so we need to re-assign it: + response[2] = body end unless headers[CACHE_CONTROL] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rack/mock_response.rb new/lib/rack/mock_response.rb --- old/lib/rack/mock_response.rb 2025-03-10 22:22:08.000000000 +0100 +++ new/lib/rack/mock_response.rb 1980-01-02 01:00:00.000000000 +0100 @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'cgi/cookie' require 'time' require_relative 'response' @@ -11,6 +10,36 @@ # MockRequest. class MockResponse < Rack::Response + begin + # Recent versions of the CGI gem may not provide `CGI::Cookie`. + require 'cgi/cookie' + Cookie = CGI::Cookie + rescue LoadError + class Cookie + attr_reader :name, :value, :path, :domain, :expires, :secure + + def initialize(args) + @name = args["name"] + @value = args["value"] + @path = args["path"] + @domain = args["domain"] + @expires = args["expires"] + @secure = args["secure"] + end + + def method_missing(method_name, *args, &block) + @value.send(method_name, *args, &block) + end + # :nocov: + ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true) + # :nocov: + + def respond_to_missing?(method_name, include_all = false) + @value.respond_to?(method_name, include_all) || super + end + end + end + class << self alias [] new end @@ -83,7 +112,7 @@ Array(set_cookie_header).each do |cookie| cookie_name, cookie_filling = cookie.split('=', 2) cookie_attributes = identify_cookie_attributes cookie_filling - parsed_cookie = CGI::Cookie.new( + parsed_cookie = Cookie.new( 'name' => cookie_name.strip, 'value' => cookie_attributes.fetch('value'), 'path' => cookie_attributes.fetch('path', nil), @@ -100,7 +129,7 @@ def identify_cookie_attributes(cookie_filling) cookie_bits = cookie_filling.split(';') cookie_attributes = Hash.new - cookie_attributes.store('value', cookie_bits[0].strip) + cookie_attributes.store('value', Array(cookie_bits[0].strip)) cookie_bits.drop(1).each do |bit| if bit.include? '=' cookie_attribute, attribute_value = bit.split('=', 2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rack/query_parser.rb new/lib/rack/query_parser.rb --- old/lib/rack/query_parser.rb 2025-03-10 22:22:08.000000000 +0100 +++ new/lib/rack/query_parser.rb 1980-01-02 01:00:00.000000000 +0100 @@ -21,21 +21,47 @@ include BadRequest end - # ParamsTooDeepError is the error that is raised when params are recursively - # nested over the specified limit. - class ParamsTooDeepError < RangeError + # QueryLimitError is for errors raised when the query provided exceeds one + # of the query parser limits. + class QueryLimitError < RangeError include BadRequest end - def self.make_default(param_depth_limit) - new Params, param_depth_limit + # ParamsTooDeepError is the old name for the error that is raised when params + # are recursively nested over the specified limit. Make it the same as + # as QueryLimitError, so that code that rescues ParamsTooDeepError error + # to handle bad query strings also now handles other limits. + ParamsTooDeepError = QueryLimitError + + def self.make_default(param_depth_limit, **options) + new(Params, param_depth_limit, **options) end attr_reader :param_depth_limit - def initialize(params_class, param_depth_limit) + env_int = lambda do |key, val| + if str_val = ENV[key] + begin + val = Integer(str_val, 10) + rescue ArgumentError + raise ArgumentError, "non-integer value provided for environment variable #{key}" + end + end + + val + end + + BYTESIZE_LIMIT = env_int.call("RACK_QUERY_PARSER_BYTESIZE_LIMIT", 4194304) + private_constant :BYTESIZE_LIMIT + + PARAMS_LIMIT = env_int.call("RACK_QUERY_PARSER_PARAMS_LIMIT", 4096) + private_constant :PARAMS_LIMIT + + def initialize(params_class, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT) @params_class = params_class @param_depth_limit = param_depth_limit + @bytesize_limit = bytesize_limit + @params_limit = params_limit end # Stolen from Mongrel, with some small modifications: @@ -47,7 +73,7 @@ params = make_params - (qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| + check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| next if p.empty? k, v = p.split('=', 2).map!(&unescaper) @@ -74,7 +100,7 @@ params = make_params unless qs.nil? || qs.empty? - (qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| + check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| k, v = p.split('=', 2).map! { |s| unescape(s) } _normalize_params(params, k, v, 0) @@ -189,6 +215,22 @@ true end + def check_query_string(qs, sep) + if qs + if qs.bytesize > @bytesize_limit + raise QueryLimitError, "total query size (#{qs.bytesize}) exceeds limit (#{@bytesize_limit})" + end + + if (param_count = qs.count(sep.is_a?(String) ? sep : '&')) >= @params_limit + raise QueryLimitError, "total number of query parameters (#{param_count+1}) exceeds limit (#{@params_limit})" + end + + qs + else + '' + end + end + def unescape(string, encoding = Encoding::UTF_8) URI.decode_www_form_component(string, encoding) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/rack/version.rb new/lib/rack/version.rb --- old/lib/rack/version.rb 2025-03-10 22:22:08.000000000 +0100 +++ new/lib/rack/version.rb 1980-01-02 01:00:00.000000000 +0100 @@ -12,7 +12,7 @@ # so it should be enough just to <tt>require 'rack'</tt> in your code. module Rack - RELEASE = "3.1.12" + RELEASE = "3.1.15" # Return the Rack release as a dotted string. def self.release diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2025-03-10 22:22:08.000000000 +0100 +++ new/metadata 1980-01-02 01:00:00.000000000 +0100 @@ -1,13 +1,13 @@ --- !ruby/object:Gem::Specification name: rack version: !ruby/object:Gem::Version - version: 3.1.12 + version: 3.1.15 platform: ruby authors: - Leah Neukirchen bindir: bin cert_chain: [] -date: 2025-03-10 00:00:00.000000000 Z +date: 1980-01-02 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: minitest @@ -75,9 +75,9 @@ executables: [] extensions: [] extra_rdoc_files: -- README.md - CHANGELOG.md - CONTRIBUTING.md +- README.md files: - CHANGELOG.md - CONTRIBUTING.md @@ -156,7 +156,7 @@ - !ruby/object:Gem::Version version: '0' requirements: [] -rubygems_version: 3.6.2 +rubygems_version: 3.6.7 specification_version: 4 summary: A modular Ruby webserver interface. test_files: []