i8c-stream-2.5
changed/i8c-stream-2.5/ruby-2.5.9-111.module+el8.9.0+19193+435404ae
parent
2431052dfc
commit
548db1d4ab
@ -0,0 +1,69 @@
|
||||
From 9d98bfe7f1abdeda5aedf9404588104980ee7a86 Mon Sep 17 00:00:00 2001
|
||||
From: aycabta <aycabta@gmail.com>
|
||||
Date: Mon, 15 Jan 2018 22:32:56 +0900
|
||||
Subject: [PATCH] Check nil text token
|
||||
|
||||
Sometimes :on_ignored_nl token has nil text. This commit checks and
|
||||
bypasses the token.
|
||||
---
|
||||
lib/rdoc/parser/ripper_state_lex.rb | 4 +++-
|
||||
test/test_rdoc_parser_ruby.rb | 30 +++++++++++++++++++++++++++++
|
||||
2 files changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/rdoc/parser/ripper_state_lex.rb b/lib/rdoc/parser/ripper_state_lex.rb
|
||||
index 2a285b97a4..c56cef46ee 100644
|
||||
--- a/lib/rdoc/parser/ripper_state_lex.rb
|
||||
+++ b/lib/rdoc/parser/ripper_state_lex.rb
|
||||
@@ -330,8 +330,10 @@ class RDoc::RipperStateLex
|
||||
@heredoc_queue << retrieve_heredoc_info(tk)
|
||||
@inner_lex.lex_state = EXPR_END unless RIPPER_HAS_LEX_STATE
|
||||
when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then
|
||||
- unless @heredoc_queue.empty?
|
||||
+ if !@heredoc_queue.empty?
|
||||
get_heredoc_tk(*@heredoc_queue.shift)
|
||||
+ elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil
|
||||
+ tk[:text] = ''
|
||||
end
|
||||
when :on_words_beg then
|
||||
tk = get_words_tk(tk)
|
||||
diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb
|
||||
index 833ed2cc74..c9d57021ce 100644
|
||||
--- a/test/rdoc/test_rdoc_parser_ruby.rb
|
||||
+++ b/test/rdoc/test_rdoc_parser_ruby.rb
|
||||
@@ -306,6 +306,36 @@ def sum(n)
|
||||
assert_equal @top_level, sum.file
|
||||
end
|
||||
|
||||
+ def test_parse_on_ignored_nl_with_nil_text
|
||||
+ util_parser <<ruby
|
||||
+class Foo
|
||||
+ def meth
|
||||
+ variable # comment
|
||||
+ .chain
|
||||
+ end
|
||||
+end
|
||||
+ruby
|
||||
+
|
||||
+ expected = <<EXPECTED
|
||||
+<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">meth</span>
|
||||
+ <span class="ruby-identifier">variable</span> <span class="ruby-comment"># comment</span>
|
||||
+ .<span class="ruby-identifier">chain</span>
|
||||
+<span class="ruby-keyword">end</span>
|
||||
+EXPECTED
|
||||
+ expected = expected.rstrip
|
||||
+
|
||||
+ @parser.scan
|
||||
+
|
||||
+ foo = @store.find_class_named 'Foo'
|
||||
+ meth = foo.method_list.first
|
||||
+
|
||||
+ assert_equal 'meth', meth.name
|
||||
+ assert_equal @top_level, meth.file
|
||||
+
|
||||
+ markup_code = meth.markup_code.sub(/^.*\n/, '')
|
||||
+ assert_equal expected, markup_code
|
||||
+ end
|
||||
+
|
||||
def test_parse_alias
|
||||
klass = RDoc::NormalClass.new 'Foo'
|
||||
klass.parent = @top_level
|
@ -0,0 +1,73 @@
|
||||
From 8e2ed0b9d965a526b29f9dc3bff8e9fe33dae98d Mon Sep 17 00:00:00 2001
|
||||
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
|
||||
Date: Tue, 12 Apr 2022 11:49:45 +0000
|
||||
Subject: [PATCH] Fix CVE-2022-28739 Buffer overrun in str2float.
|
||||
|
||||
CVE-2022-28739: Buffer overrun in String-to-Float conversion
|
||||
Backported from upstream Ruby 2.6.10,
|
||||
Git commit:
|
||||
https://github.com/ruby/ruby/commit/69f9992ed41920389d4185141a14f02f89a4d306
|
||||
|
||||
==== Original commit message
|
||||
|
||||
Fix dtoa buffer overrun
|
||||
|
||||
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67957 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
||||
---
|
||||
test/ruby/test_float.rb | 18 ++++++++++++++++++
|
||||
util.c | 3 ++-
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
|
||||
index 7fabfd3..78c63c2 100644
|
||||
--- a/test/ruby/test_float.rb
|
||||
+++ b/test/ruby/test_float.rb
|
||||
@@ -171,6 +171,24 @@ class TestFloat < Test::Unit::TestCase
|
||||
assert_raise(ArgumentError, n += z + "A") {Float(n)}
|
||||
assert_raise(ArgumentError, n += z + ".0") {Float(n)}
|
||||
end
|
||||
+
|
||||
+ x = nil
|
||||
+ 2000.times do
|
||||
+ x = Float("0x"+"0"*30)
|
||||
+ break unless x == 0.0
|
||||
+ end
|
||||
+ assert_equal(0.0, x, ->{"%a" % x})
|
||||
+ x = nil
|
||||
+ 2000.times do
|
||||
+ begin
|
||||
+ x = Float("0x1."+"0"*270)
|
||||
+ rescue ArgumentError => e
|
||||
+ raise unless /"0x1\.0{270}"/ =~ e.message
|
||||
+ else
|
||||
+ break
|
||||
+ end
|
||||
+ end
|
||||
+ assert_nil(x, ->{"%a" % x})
|
||||
end
|
||||
|
||||
def test_divmod
|
||||
diff --git a/util.c b/util.c
|
||||
index 2222744..f1d910f 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -2046,6 +2046,7 @@ break2:
|
||||
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
|
||||
if (*s == '0') {
|
||||
while (*++s == '0');
|
||||
+ if (!*s) goto ret;
|
||||
s1 = strchr(hexdigit, *s);
|
||||
}
|
||||
if (s1 != NULL) {
|
||||
@@ -2068,7 +2069,7 @@ break2:
|
||||
for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
|
||||
adj += aadj * ((s1 - hexdigit) & 15);
|
||||
if ((aadj /= 16) == 0.0) {
|
||||
- while (strchr(hexdigit, *++s));
|
||||
+ while (*++s && strchr(hexdigit, *s));
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,328 @@
|
||||
From 8fc4b4792919c627183f4ddb6dc256aae49eb738 Mon Sep 17 00:00:00 2001
|
||||
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
|
||||
Date: Tue, 22 Nov 2022 13:48:18 +0900
|
||||
Subject: [PATCH] Fix CVE-2021-33621 HTTP response splitting in CGI.
|
||||
|
||||
Backported from upstream Ruby, commit:
|
||||
https://github.com/ruby/ruby/commit/7cf697179dab52b0d024543304f4d3ab5fa5e847
|
||||
|
||||
Test "CGICookieTest#test_cgi_cookie_new_with_domain" was adjusted to
|
||||
deal with Ruby 2.5 not allowing String with double splat operator.
|
||||
|
||||
==== Original commit message
|
||||
Merge CGI-0.1.0.2
|
||||
---
|
||||
lib/cgi/cookie.rb | 51 ++++++++++++++++-------
|
||||
lib/cgi/core.rb | 45 ++++++++++++--------
|
||||
test/cgi/test_cgi_cookie.rb | 82 +++++++++++++++++++++++++++++++++++++
|
||||
test/cgi/test_cgi_header.rb | 8 ++++
|
||||
4 files changed, 154 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
|
||||
index 009566b..f26f015 100644
|
||||
--- a/lib/cgi/cookie.rb
|
||||
+++ b/lib/cgi/cookie.rb
|
||||
@@ -40,6 +40,10 @@ class CGI
|
||||
class Cookie < Array
|
||||
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
|
||||
|
||||
+ TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
|
||||
+ PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
|
||||
+ DOMAIN_VALUE_RE = %r"\A(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
|
||||
+
|
||||
# Create a new CGI::Cookie object.
|
||||
#
|
||||
# :call-seq:
|
||||
@@ -72,9 +76,8 @@ class CGI
|
||||
@domain = nil
|
||||
@expires = nil
|
||||
if name.kind_of?(String)
|
||||
- @name = name
|
||||
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
|
||||
- @path = ($1 or "")
|
||||
+ self.name = name
|
||||
+ self.path = (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
|
||||
@secure = false
|
||||
@httponly = false
|
||||
return super(value)
|
||||
@@ -85,16 +88,11 @@ class CGI
|
||||
raise ArgumentError, "`name' required"
|
||||
end
|
||||
|
||||
- @name = options["name"]
|
||||
+ self.name = options["name"]
|
||||
value = Array(options["value"])
|
||||
# simple support for IE
|
||||
- if options["path"]
|
||||
- @path = options["path"]
|
||||
- else
|
||||
- %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
|
||||
- @path = ($1 or "")
|
||||
- end
|
||||
- @domain = options["domain"]
|
||||
+ self.path = options["path"] || (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
|
||||
+ self.domain = options["domain"]
|
||||
@expires = options["expires"]
|
||||
@secure = options["secure"] == true
|
||||
@httponly = options["httponly"] == true
|
||||
@@ -102,12 +100,35 @@ class CGI
|
||||
super(value)
|
||||
end
|
||||
|
||||
- # Name of this cookie, as a +String+
|
||||
- attr_accessor :name
|
||||
+ attr_reader :name
|
||||
+ # Set name of this cookie
|
||||
+ def name=(str)
|
||||
+ if str and !TOKEN_RE.match?(str)
|
||||
+ raise ArgumentError, "invalid name: #{str.dump}"
|
||||
+ end
|
||||
+ @name = str
|
||||
+ end
|
||||
+
|
||||
# Path for which this cookie applies, as a +String+
|
||||
- attr_accessor :path
|
||||
+ attr_reader :path
|
||||
+ # Set path for which this cookie applies
|
||||
+ def path=(str)
|
||||
+ if str and !PATH_VALUE_RE.match?(str)
|
||||
+ raise ArgumentError, "invalid path: #{str.dump}"
|
||||
+ end
|
||||
+ @path = str
|
||||
+ end
|
||||
+
|
||||
# Domain for which this cookie applies, as a +String+
|
||||
- attr_accessor :domain
|
||||
+ attr_reader :domain
|
||||
+ # Set domain for which this cookie applies
|
||||
+ def domain=(str)
|
||||
+ if str and ((str = str.b).bytesize > 255 or !DOMAIN_VALUE_RE.match?(str))
|
||||
+ raise ArgumentError, "invalid domain: #{str.dump}"
|
||||
+ end
|
||||
+ @domain = str
|
||||
+ end
|
||||
+
|
||||
# Time at which this cookie expires, as a +Time+
|
||||
attr_accessor :expires
|
||||
# True if this cookie is secure; false otherwise
|
||||
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
|
||||
index 9bd7798..7d8b223 100644
|
||||
--- a/lib/cgi/core.rb
|
||||
+++ b/lib/cgi/core.rb
|
||||
@@ -188,17 +188,28 @@ class CGI
|
||||
# Using #header with the HTML5 tag maker will create a <header> element.
|
||||
alias :header :http_header
|
||||
|
||||
+ def _no_crlf_check(str)
|
||||
+ if str
|
||||
+ str = str.to_s
|
||||
+ raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
|
||||
+ str
|
||||
+ else
|
||||
+ nil
|
||||
+ end
|
||||
+ end
|
||||
+ private :_no_crlf_check
|
||||
+
|
||||
def _header_for_string(content_type) #:nodoc:
|
||||
buf = ''.dup
|
||||
if nph?()
|
||||
- buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
+ buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
- buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
|
||||
+ buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
|
||||
buf << "Connection: close#{EOL}"
|
||||
end
|
||||
- buf << "Content-Type: #{content_type}#{EOL}"
|
||||
+ buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||
+ @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
|
||||
end
|
||||
return buf
|
||||
end # _header_for_string
|
||||
@@ -213,9 +224,9 @@ class CGI
|
||||
## NPH
|
||||
options.delete('nph') if defined?(MOD_RUBY)
|
||||
if options.delete('nph') || nph?()
|
||||
- protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
||||
+ protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
|
||||
status = options.delete('status')
|
||||
- status = HTTP_STATUS[status] || status || '200 OK'
|
||||
+ status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
|
||||
buf << "#{protocol} #{status}#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
|
||||
@@ -223,38 +234,38 @@ class CGI
|
||||
end
|
||||
## common headers
|
||||
status = options.delete('status')
|
||||
- buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
|
||||
+ buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
|
||||
server = options.delete('server')
|
||||
- buf << "Server: #{server}#{EOL}" if server
|
||||
+ buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
|
||||
connection = options.delete('connection')
|
||||
- buf << "Connection: #{connection}#{EOL}" if connection
|
||||
+ buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
|
||||
type = options.delete('type')
|
||||
- buf << "Content-Type: #{type}#{EOL}" #if type
|
||||
+ buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
|
||||
length = options.delete('length')
|
||||
- buf << "Content-Length: #{length}#{EOL}" if length
|
||||
+ buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
|
||||
language = options.delete('language')
|
||||
- buf << "Content-Language: #{language}#{EOL}" if language
|
||||
+ buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
|
||||
expires = options.delete('expires')
|
||||
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
|
||||
## cookie
|
||||
if cookie = options.delete('cookie')
|
||||
case cookie
|
||||
when String, Cookie
|
||||
- buf << "Set-Cookie: #{cookie}#{EOL}"
|
||||
+ buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
|
||||
when Array
|
||||
arr = cookie
|
||||
- arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
when Hash
|
||||
hash = cookie
|
||||
- hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
end
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
## other headers
|
||||
options.each do |key, value|
|
||||
- buf << "#{key}: #{value}#{EOL}"
|
||||
+ buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
|
||||
end
|
||||
return buf
|
||||
end # _header_for_hash
|
||||
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
|
||||
index 985cc0d..7afff5e 100644
|
||||
--- a/test/cgi/test_cgi_cookie.rb
|
||||
+++ b/test/cgi/test_cgi_cookie.rb
|
||||
@@ -60,6 +60,24 @@ class CGICookieTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
|
||||
+ def test_cgi_cookie_new_with_domain
|
||||
+ h = {'name'=>'name1', 'value'=>'value1'}
|
||||
+ cookie = CGI::Cookie.new({'domain' => 'a.example.com'}.merge(h))
|
||||
+ assert_equal('a.example.com', cookie.domain)
|
||||
+
|
||||
+ cookie = CGI::Cookie.new({'domain'=>'1.example.com'}.merge(h))
|
||||
+ assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
|
||||
+
|
||||
+ assert_raise(ArgumentError) {
|
||||
+ CGI::Cookie.new({'domain'=>'-a.example.com'}.merge(h))
|
||||
+ }
|
||||
+
|
||||
+ assert_raise(ArgumentError) {
|
||||
+ CGI::Cookie.new({'domain'=>'a-.example.com'}.merge(h))
|
||||
+ }
|
||||
+ end
|
||||
+
|
||||
+
|
||||
def test_cgi_cookie_scriptname
|
||||
cookie = CGI::Cookie.new('name1', 'value1')
|
||||
assert_equal('', cookie.path)
|
||||
@@ -118,6 +136,70 @@ class CGICookieTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
|
||||
+ def test_cgi_cookie_domain_injection_into_name
|
||||
+ name = "a=b; domain=example.com;"
|
||||
+ path = "/"
|
||||
+ domain = "example.jp"
|
||||
+ assert_raise(ArgumentError) do
|
||||
+ CGI::Cookie.new('name' => name,
|
||||
+ 'value' => "value",
|
||||
+ 'domain' => domain,
|
||||
+ 'path' => path)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ def test_cgi_cookie_newline_injection_into_name
|
||||
+ name = "a=b;\r\nLocation: http://example.com#"
|
||||
+ path = "/"
|
||||
+ domain = "example.jp"
|
||||
+ assert_raise(ArgumentError) do
|
||||
+ CGI::Cookie.new('name' => name,
|
||||
+ 'value' => "value",
|
||||
+ 'domain' => domain,
|
||||
+ 'path' => path)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ def test_cgi_cookie_multibyte_injection_into_name
|
||||
+ name = "a=b;\u3042"
|
||||
+ path = "/"
|
||||
+ domain = "example.jp"
|
||||
+ assert_raise(ArgumentError) do
|
||||
+ CGI::Cookie.new('name' => name,
|
||||
+ 'value' => "value",
|
||||
+ 'domain' => domain,
|
||||
+ 'path' => path)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ def test_cgi_cookie_injection_into_path
|
||||
+ name = "name"
|
||||
+ path = "/; samesite=none"
|
||||
+ domain = "example.jp"
|
||||
+ assert_raise(ArgumentError) do
|
||||
+ CGI::Cookie.new('name' => name,
|
||||
+ 'value' => "value",
|
||||
+ 'domain' => domain,
|
||||
+ 'path' => path)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+
|
||||
+ def test_cgi_cookie_injection_into_domain
|
||||
+ name = "name"
|
||||
+ path = "/"
|
||||
+ domain = "example.jp; samesite=none"
|
||||
+ assert_raise(ArgumentError) do
|
||||
+ CGI::Cookie.new('name' => name,
|
||||
+ 'value' => "value",
|
||||
+ 'domain' => domain,
|
||||
+ 'path' => path)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
|
||||
instance_methods.each do |method|
|
||||
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
|
||||
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
|
||||
index bab2d03..ec2f4de 100644
|
||||
--- a/test/cgi/test_cgi_header.rb
|
||||
+++ b/test/cgi/test_cgi_header.rb
|
||||
@@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
|
||||
+ def test_cgi_http_header_crlf_injection
|
||||
+ cgi = CGI.new
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
|
||||
+ end
|
||||
+
|
||||
|
||||
instance_methods.each do |method|
|
||||
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 61fb466ea0b492c990fcd2d681c08f2001d7a659 Mon Sep 17 00:00:00 2001
|
||||
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
|
||||
Date: Tue, 28 Mar 2023 17:33:19 +0900
|
||||
Subject: [PATCH] Fix CVE-2023-28755 ReDos vulnerability in URI.
|
||||
|
||||
This patch was backported from Ruby 2.7.8
|
||||
|
||||
Backported from upstream Ruby, commit:
|
||||
https://github.com/ruby/ruby/commit/6855779d580358a6a0b4c9ee06f20e7cae72955a
|
||||
|
||||
===== Original commit message
|
||||
|
||||
Merge URI-0.10.0.2
|
||||
---
|
||||
lib/uri/rfc3986_parser.rb | 4 ++--
|
||||
test/uri/test_parser.rb | 7 +++++++
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb
|
||||
index 8712800..ad32368 100644
|
||||
--- a/lib/uri/rfc3986_parser.rb
|
||||
+++ b/lib/uri/rfc3986_parser.rb
|
||||
@@ -3,8 +3,8 @@ module URI
|
||||
class RFC3986_Parser # :nodoc:
|
||||
# URI defined in RFC3986
|
||||
# this regexp is modified not to host is not empty string
|
||||
- RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
|
||||
- RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
|
||||
+ RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
|
||||
+ RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
|
||||
attr_reader :regexp
|
||||
|
||||
def initialize
|
||||
diff --git a/test/uri/test_parser.rb b/test/uri/test_parser.rb
|
||||
index 757ac86..2f70559 100644
|
||||
--- a/test/uri/test_parser.rb
|
||||
+++ b/test/uri/test_parser.rb
|
||||
@@ -45,4 +45,11 @@ class URI::TestParser < Test::Unit::TestCase
|
||||
URI.parse(1)
|
||||
end
|
||||
end
|
||||
+
|
||||
+ def test_split
|
||||
+ assert_equal(["http", nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("http://example.com"))
|
||||
+ assert_equal(["http", nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("http://[0::0]"))
|
||||
+ assert_equal([nil, nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("//example.com"))
|
||||
+ assert_equal([nil, nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("//[0::0]"))
|
||||
+ end
|
||||
end
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,41 @@
|
||||
From 71c37c29defeab2c98ad4291807efe12427a209f Mon Sep 17 00:00:00 2001
|
||||
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
Date: Tue, 29 Nov 2022 16:22:15 +0900
|
||||
Subject: [PATCH] Fix CVE-2023-28756 ReDoS vulnerability in Time.
|
||||
|
||||
Backported from: Ruby 2.7.8
|
||||
Backported from the following commits:
|
||||
https://github.com/ruby/ruby/commit/2cb830602f52e7e76c6781115e7938b21f881c4f
|
||||
https://github.com/ruby/ruby/commit/e3f18f7d2e034f20053d7bf2fc7a50f8b7e1a27a
|
||||
|
||||
Do not include the test case, as assert_linear_time was introduced in Ruby 2.7.
|
||||
|
||||
==== Original commit message(s)
|
||||
|
||||
Fix quadratic backtracking on invalid time
|
||||
|
||||
Make RFC2822 regexp linear
|
||||
|
||||
https://hackerone.com/reports/1485501
|
||||
---
|
||||
lib/time.rb | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/time.rb b/lib/time.rb
|
||||
index eb46a03..cb6f1e4 100644
|
||||
--- a/lib/time.rb
|
||||
+++ b/lib/time.rb
|
||||
@@ -474,8 +474,8 @@ class Time
|
||||
(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
|
||||
(\d{2,})\s+
|
||||
(\d{2})\s*
|
||||
- :\s*(\d{2})\s*
|
||||
- (?::\s*(\d{2}))?\s+
|
||||
+ :\s*(\d{2})
|
||||
+ (?:\s*:\s*(\d\d))?\s+
|
||||
([+-]\d{4}|
|
||||
UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date
|
||||
# Since RFC 2822 permit comments, the regexp has no right anchor.
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,70 @@
|
||||
From a1124dc162810f86cb0bff58cde24064cfc561bc Mon Sep 17 00:00:00 2001
|
||||
From: nagachika <nagachika@ruby-lang.org>
|
||||
Date: Fri, 9 Dec 2022 21:11:47 +0900
|
||||
Subject: [PATCH] merge revision(s) 58cc3c9f387dcf8f820b43e043b540fa06248da3:
|
||||
[Backport #19187]
|
||||
|
||||
[Bug #19187] Fix for tzdata-2022g
|
||||
|
||||
---
|
||||
test/ruby/test_time_tz.rb | 21 +++++++++++++++------
|
||||
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||
---
|
||||
test/ruby/test_time_tz.rb | 21 +++++++++++++++------
|
||||
1 files changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
|
||||
index b6785f336028d..939f218ed4d10 100644
|
||||
--- a/test/ruby/test_time_tz.rb
|
||||
+++ b/test/ruby/test_time_tz.rb
|
||||
@@ -6,9 +6,9 @@ class TestTimeTZ < Test::Unit::TestCase
|
||||
has_lisbon_tz = true
|
||||
force_tz_test = ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes"
|
||||
case RUBY_PLATFORM
|
||||
- when /linux/
|
||||
+ when /darwin|linux/
|
||||
force_tz_test = true
|
||||
- when /darwin|freebsd/
|
||||
+ when /freebsd|openbsd/
|
||||
has_lisbon_tz = false
|
||||
force_tz_test = true
|
||||
end
|
||||
@@ -94,6 +94,9 @@ def group_by(e, &block)
|
||||
CORRECT_KIRITIMATI_SKIP_1994 = with_tz("Pacific/Kiritimati") {
|
||||
Time.local(1994, 12, 31, 0, 0, 0).year == 1995
|
||||
}
|
||||
+ CORRECT_SINGAPORE_1982 = with_tz("Asia/Singapore") {
|
||||
+ "2022g" if Time.local(1981, 12, 31, 23, 59, 59).utc_offset == 8*3600
|
||||
+ }
|
||||
|
||||
def time_to_s(t)
|
||||
t.to_s
|
||||
@@ -139,9 +142,12 @@ def test_america_managua
|
||||
|
||||
def test_asia_singapore
|
||||
with_tz(tz="Asia/Singapore") {
|
||||
- assert_time_constructor(tz, "1981-12-31 23:59:59 +0730", :local, [1981,12,31,23,59,59])
|
||||
- assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,0,0])
|
||||
- assert_time_constructor(tz, "1982-01-01 00:59:59 +0800", :local, [1982,1,1,0,29,59])
|
||||
+ assert_time_constructor(tz, "1981-12-31 23:29:59 +0730", :local, [1981,12,31,23,29,59])
|
||||
+ if CORRECT_SINGAPORE_1982
|
||||
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1981,12,31,23,30,00])
|
||||
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1982,1,1,0,0,0])
|
||||
+ assert_time_constructor(tz, "1982-01-01 00:29:59 +0800", :local, [1982,1,1,0,29,59])
|
||||
+ end
|
||||
assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,30,0])
|
||||
}
|
||||
end
|
||||
@@ -364,8 +370,11 @@ def self.gen_zdump_test(data)
|
||||
America/Managua Wed Jan 1 04:59:59 1997 UTC = Tue Dec 31 23:59:59 1996 EST isdst=0 gmtoff=-18000
|
||||
America/Managua Wed Jan 1 05:00:00 1997 UTC = Tue Dec 31 23:00:00 1996 CST isdst=0 gmtoff=-21600
|
||||
Asia/Singapore Sun Aug 8 16:30:00 1965 UTC = Mon Aug 9 00:00:00 1965 SGT isdst=0 gmtoff=27000
|
||||
-Asia/Singapore Thu Dec 31 16:29:59 1981 UTC = Thu Dec 31 23:59:59 1981 SGT isdst=0 gmtoff=27000
|
||||
+Asia/Singapore Thu Dec 31 15:59:59 1981 UTC = Thu Dec 31 23:29:59 1981 SGT isdst=0 gmtoff=27000
|
||||
Asia/Singapore Thu Dec 31 16:30:00 1981 UTC = Fri Jan 1 00:30:00 1982 SGT isdst=0 gmtoff=28800
|
||||
+End
|
||||
+ gen_zdump_test <<'End' if CORRECT_SINGAPORE_1982
|
||||
+Asia/Singapore Thu Dec 31 16:00:00 1981 UTC = Fri Jan 1 00:00:00 1982 SGT isdst=0 gmtoff=28800
|
||||
End
|
||||
gen_zdump_test CORRECT_TOKYO_DST_1951 ? <<'End' + (CORRECT_TOKYO_DST_1951 < "2018f" ? <<'2018e' : <<'2018f') : <<'End'
|
||||
Asia/Tokyo Sat May 5 14:59:59 1951 UTC = Sat May 5 23:59:59 1951 JST isdst=0 gmtoff=32400
|
@ -0,0 +1,27 @@
|
||||
From dae843f6b7502f921a7e66f39e3714a39d860181 Mon Sep 17 00:00:00 2001
|
||||
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
|
||||
Date: Wed, 19 Oct 2022 19:40:00 +0900
|
||||
Subject: [PATCH] Bypass git submodule add/update with git config
|
||||
protocol.file.allow=always option.
|
||||
|
||||
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
---
|
||||
test/rubygems/test_gem_source_git.rb | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb
|
||||
index 5702da05974b6..c3b324771fa4d 100644
|
||||
--- a/test/rubygems/test_gem_source_git.rb
|
||||
+++ b/test/rubygems/test_gem_source_git.rb
|
||||
@@ -64,6 +64,11 @@ def test_checkout_local_cached
|
||||
end
|
||||
|
||||
def test_checkout_submodules
|
||||
+ # We need to allow to checkout submodules with file:// protocol
|
||||
+ # CVE-2022-39253
|
||||
+ # https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
|
||||
+ system(@git, *%W"config --global protocol.file.allow always")
|
||||
+
|
||||
source = Gem::Source::Git.new @name, @repository, 'master', true
|
||||
|
||||
git_gem 'b'
|
@ -0,0 +1,41 @@
|
||||
From 5e09d632f3b56d85b2659ab47d5571ae9e270e10 Mon Sep 17 00:00:00 2001
|
||||
From: Xenor Chang <tubaxenor@gmail.com>
|
||||
Date: Mon, 28 Nov 2022 12:34:06 +0800
|
||||
Subject: [PATCH] Loosen the domain regex to accept '.' (#29)
|
||||
|
||||
* Loosen the domain regex to accept '.'
|
||||
|
||||
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
Co-authored-by: Hiroshi SHIBATA <hsbt@ruby-lang.org>
|
||||
---
|
||||
lib/cgi/cookie.rb | 2 +-
|
||||
test/cgi/test_cgi_cookie.rb | 3 +++
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
|
||||
index 1a9c1a8..9498e2f 100644
|
||||
--- a/lib/cgi/cookie.rb
|
||||
+++ b/lib/cgi/cookie.rb
|
||||
@@ -42,7 +42,7 @@ class Cookie < Array
|
||||
|
||||
TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
|
||||
PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
|
||||
- DOMAIN_VALUE_RE = %r"\A(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
|
||||
+ DOMAIN_VALUE_RE = %r"\A\.?(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
|
||||
|
||||
# Create a new CGI::Cookie object.
|
||||
#
|
||||
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
|
||||
index 6d31932..eadae45 100644
|
||||
--- a/test/cgi/test_cgi_cookie.rb
|
||||
+++ b/test/cgi/test_cgi_cookie.rb
|
||||
@@ -65,6 +65,9 @@ class CGICookieTest < Test::Unit::TestCase
|
||||
cookie = CGI::Cookie.new({'domain' => 'a.example.com'}.merge(h))
|
||||
assert_equal('a.example.com', cookie.domain)
|
||||
|
||||
+ cookie = CGI::Cookie.new(h.merge('domain'=>'.example.com'))
|
||||
+ assert_equal('.example.com', cookie.domain)
|
||||
+
|
||||
cookie = CGI::Cookie.new({'domain'=>'1.example.com'}.merge(h))
|
||||
assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
|
||||
|
Loading…
Reference in new issue