Compare commits

..

1 Commits

Author SHA1 Message Date
eabdullin 9f77644df1 AlmaLinux changes 2021-11-17 16:29:58 +03:00
17 changed files with 146 additions and 2232 deletions

View File

@ -0,0 +1,116 @@
From 346e147ba6480839b87046e9a9efab0bf6ed3660 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Wed, 10 Aug 2016 17:35:48 +0200
Subject: [PATCH] Rely on ldd to detect glibc.
This is just workaround, since we know we are quite sure this will be successful
on Red Hat platforms.
This workaround rhbz#1361037
---
test/fiddle/helper.rb | 92 ---------------------------------------------------
1 file changed, 92 deletions(-)
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
index 1da3d93..65148a1 100644
--- a/test/fiddle/helper.rb
+++ b/test/fiddle/helper.rb
@@ -6,95 +6,6 @@
libc_so = libm_so = nil
-case RUBY_PLATFORM
-when /cygwin/
- libc_so = "cygwin1.dll"
- libm_so = "cygwin1.dll"
-when /linux/
- libdir = '/lib'
- case [0].pack('L!').size
- when 4
- # 32-bit ruby
- libdir = '/lib32' if File.directory? '/lib32'
- when 8
- # 64-bit ruby
- libdir = '/lib64' if File.directory? '/lib64'
- end
- libc_so = File.join(libdir, "libc.so.6")
- libm_so = File.join(libdir, "libm.so.6")
-when /mingw/, /mswin/
- require "rbconfig"
- crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'
- libc_so = libm_so = "#{crtname}.dll"
-when /darwin/
- libc_so = "/usr/lib/libc.dylib"
- libm_so = "/usr/lib/libm.dylib"
-when /kfreebsd/
- libc_so = "/lib/libc.so.0.1"
- libm_so = "/lib/libm.so.1"
-when /gnu/ #GNU/Hurd
- libc_so = "/lib/libc.so.0.3"
- libm_so = "/lib/libm.so.6"
-when /mirbsd/
- libc_so = "/usr/lib/libc.so.41.10"
- libm_so = "/usr/lib/libm.so.7.0"
-when /freebsd/
- libc_so = "/lib/libc.so.7"
- libm_so = "/lib/libm.so.5"
-when /bsd|dragonfly/
- libc_so = "/usr/lib/libc.so"
- libm_so = "/usr/lib/libm.so"
-when /solaris/
- libdir = '/lib'
- case [0].pack('L!').size
- when 4
- # 32-bit ruby
- libdir = '/lib' if File.directory? '/lib'
- when 8
- # 64-bit ruby
- libdir = '/lib/64' if File.directory? '/lib/64'
- end
- libc_so = File.join(libdir, "libc.so")
- libm_so = File.join(libdir, "libm.so")
-when /aix/
- pwd=Dir.pwd
- libc_so = libm_so = "#{pwd}/libaixdltest.so"
- unless File.exist? libc_so
- cobjs=%w!strcpy.o!
- mobjs=%w!floats.o sin.o!
- funcs=%w!sin sinf strcpy strncpy!
- expfile='dltest.exp'
- require 'tmpdir'
- Dir.mktmpdir do |dir|
- begin
- Dir.chdir dir
- %x!/usr/bin/ar x /usr/lib/libc.a #{cobjs.join(' ')}!
- %x!/usr/bin/ar x /usr/lib/libm.a #{mobjs.join(' ')}!
- %x!echo "#{funcs.join("\n")}\n" > #{expfile}!
- require 'rbconfig'
- if RbConfig::CONFIG["GCC"] = 'yes'
- lflag='-Wl,'
- else
- lflag=''
- end
- flags="#{lflag}-bE:#{expfile} #{lflag}-bnoentry -lm"
- %x!#{RbConfig::CONFIG["LDSHARED"]} -o #{libc_so} #{(cobjs+mobjs).join(' ')} #{flags}!
- ensure
- Dir.chdir pwd
- end
- end
- end
-else
- libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
- libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
- if( !(libc_so && libm_so) )
- $stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
- end
-end
-
-libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
-libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
-
if !libc_so || !libm_so
ruby = EnvUtil.rubybin
ldd = `ldd #{ruby}`
--
2.9.2

View File

@ -0,0 +1,12 @@
diff -uprN a/test/ruby/test_process.rb b/test/ruby/test_process.rb
--- a/test/ruby/test_process.rb 2021-07-07 13:21:03.853876760 +0300
+++ b/test/ruby/test_process.rb 2021-07-07 13:24:29.883818358 +0300
@@ -1852,7 +1852,7 @@ class TestProcess < Test::Unit::TestCase
end
def test_execopts_gid
- skip "Process.groups not implemented on Windows platform" if windows?
+ skip "For ARM64 platform"
feature6975 = '[ruby-core:47414]'
[30000, *Process.groups.map {|g| g = Etc.getgrgid(g); [g.name, g.gid]}].each do |group, gid|

View File

@ -1,69 +0,0 @@
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

View File

@ -1,73 +0,0 @@
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

View File

@ -1,247 +0,0 @@
commit be5a83e84a34091f2a4e3c6dfb911b20e78e690c
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed Jul 7 10:34:08 2021 +0000
Ignore IP addresses in PASV responses by default, and add new option use_pasv_ip
This fixes CVE-2021-31810.
Reported by Alexandr Savca.
Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index e68d825dcf..c5d669d898 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -97,6 +97,10 @@ class FTP < Protocol
# When +true+, the connection is in passive mode. Default: +true+.
attr_accessor :passive
+ # When +true+, use the IP address in PASV responses. Otherwise, it uses
+ # the same IP address for the control connection. Default: +false+.
+ attr_accessor :use_pasv_ip
+
# When +true+, all traffic to and from the server is written
# to +$stdout+. Default: +false+.
attr_accessor :debug_mode
@@ -205,6 +209,9 @@ def FTP.open(host, *args)
# handshake.
# See Net::FTP#ssl_handshake_timeout for
# details. Default: +nil+.
+ # use_pasv_ip:: When +true+, use the IP address in PASV responses.
+ # Otherwise, it uses the same IP address for the control
+ # connection. Default: +false+.
# debug_mode:: When +true+, all traffic to and from the server is
# written to +$stdout+. Default: +false+.
#
@@ -265,6 +272,7 @@ def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil)
@open_timeout = options[:open_timeout]
@ssl_handshake_timeout = options[:ssl_handshake_timeout]
@read_timeout = options[:read_timeout] || 60
+ @use_pasv_ip = options[:use_pasv_ip] || false
if host
connect(host, options[:port] || FTP_PORT)
if options[:username]
@@ -1330,7 +1338,12 @@ def parse227(resp) # :nodoc:
raise FTPReplyError, resp
end
if m = /\((?<host>\d+(,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
+ if @use_pasv_ip
+ host = parse_pasv_ipv4_host(m["host"])
+ else
+ host = @bare_sock.remote_address.ip_address
+ end
+ return host, parse_pasv_port(m["port"])
else
raise FTPProtoError, resp
end
diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb
index a5219644bb..b3fe7774ed 100644
--- a/test/net/ftp/test_ftp.rb
+++ b/test/net/ftp/test_ftp.rb
@@ -61,7 +61,7 @@ def test_connect_fail
end
def test_parse227
- ftp = Net::FTP.new
+ ftp = Net::FTP.new(nil, use_pasv_ip: true)
host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)")
assert_equal("192.168.0.1", host)
assert_equal(3106, port)
@@ -80,6 +80,14 @@ def test_parse227
assert_raise(Net::FTPProtoError) do
ftp.send(:parse227, "227 ) foo bar (")
end
+
+ ftp = Net::FTP.new
+ sock = OpenStruct.new
+ sock.remote_address = OpenStruct.new
+ sock.remote_address.ip_address = "10.0.0.1"
+ ftp.instance_variable_set(:@bare_sock, sock)
+ host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)")
+ assert_equal("10.0.0.1", host)
end
def test_parse228
@@ -2360,10 +2368,155 @@ def test_puttextfile_command_injection
end
end
+ def test_ignore_pasv_ip
+ commands = []
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
+ sock.print("220 (test_ftp).\r\n")
+ commands.push(sock.gets)
+ sock.print("331 Please specify the password.\r\n")
+ commands.push(sock.gets)
+ sock.print("230 Login successful.\r\n")
+ commands.push(sock.gets)
+ sock.print("200 Switching to Binary mode.\r\n")
+ line = sock.gets
+ commands.push(line)
+ data_server = TCPServer.new("127.0.0.1", 0)
+ port = data_server.local_address.ip_port
+ sock.printf("227 Entering Passive Mode (999,0,0,1,%s).\r\n",
+ port.divmod(256).join(","))
+ commands.push(sock.gets)
+ sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
+ conn = data_server.accept
+ binary_data.scan(/.{1,1024}/nm) do |s|
+ conn.print(s)
+ end
+ conn.shutdown(Socket::SHUT_WR)
+ conn.read
+ conn.close
+ data_server.close
+ sock.print("226 Transfer complete.\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.passive = true
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
+ ftp.connect("127.0.0.1", server.port)
+ ftp.login
+ assert_match(/\AUSER /, commands.shift)
+ assert_match(/\APASS /, commands.shift)
+ assert_equal("TYPE I\r\n", commands.shift)
+ buf = ftp.getbinaryfile("foo", nil)
+ assert_equal(binary_data, buf)
+ assert_equal(Encoding::ASCII_8BIT, buf.encoding)
+ assert_equal("PASV\r\n", commands.shift)
+ assert_equal("RETR foo\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_use_pasv_ip
+ commands = []
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
+ sock.print("220 (test_ftp).\r\n")
+ commands.push(sock.gets)
+ sock.print("331 Please specify the password.\r\n")
+ commands.push(sock.gets)
+ sock.print("230 Login successful.\r\n")
+ commands.push(sock.gets)
+ sock.print("200 Switching to Binary mode.\r\n")
+ line = sock.gets
+ commands.push(line)
+ data_server = TCPServer.new("127.0.0.1", 0)
+ port = data_server.local_address.ip_port
+ sock.printf("227 Entering Passive Mode (127,0,0,1,%s).\r\n",
+ port.divmod(256).join(","))
+ commands.push(sock.gets)
+ sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
+ conn = data_server.accept
+ binary_data.scan(/.{1,1024}/nm) do |s|
+ conn.print(s)
+ end
+ conn.shutdown(Socket::SHUT_WR)
+ conn.read
+ conn.close
+ data_server.close
+ sock.print("226 Transfer complete.\r\n")
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.passive = true
+ ftp.use_pasv_ip = true
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
+ ftp.connect("127.0.0.1", server.port)
+ ftp.login
+ assert_match(/\AUSER /, commands.shift)
+ assert_match(/\APASS /, commands.shift)
+ assert_equal("TYPE I\r\n", commands.shift)
+ buf = ftp.getbinaryfile("foo", nil)
+ assert_equal(binary_data, buf)
+ assert_equal(Encoding::ASCII_8BIT, buf.encoding)
+ assert_equal("PASV\r\n", commands.shift)
+ assert_equal("RETR foo\r\n", commands.shift)
+ assert_equal(nil, commands.shift)
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
+ def test_use_pasv_invalid_ip
+ commands = []
+ binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
+ server = create_ftp_server(nil, "127.0.0.1") { |sock|
+ sock.print("220 (test_ftp).\r\n")
+ commands.push(sock.gets)
+ sock.print("331 Please specify the password.\r\n")
+ commands.push(sock.gets)
+ sock.print("230 Login successful.\r\n")
+ commands.push(sock.gets)
+ sock.print("200 Switching to Binary mode.\r\n")
+ line = sock.gets
+ commands.push(line)
+ sock.print("227 Entering Passive Mode (999,0,0,1,48,57).\r\n")
+ commands.push(sock.gets)
+ }
+ begin
+ begin
+ ftp = Net::FTP.new
+ ftp.passive = true
+ ftp.use_pasv_ip = true
+ ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
+ ftp.connect("127.0.0.1", server.port)
+ ftp.login
+ assert_match(/\AUSER /, commands.shift)
+ assert_match(/\APASS /, commands.shift)
+ assert_equal("TYPE I\r\n", commands.shift)
+ assert_raise(SocketError) do
+ ftp.getbinaryfile("foo", nil)
+ end
+ ensure
+ ftp.close if ftp
+ end
+ ensure
+ server.close
+ end
+ end
+
private
- def create_ftp_server(sleep_time = nil)
- server = TCPServer.new(SERVER_ADDR, 0)
+ def create_ftp_server(sleep_time = nil, addr = SERVER_ADDR)
+ server = TCPServer.new(addr, 0)
@thread = Thread.start do
if sleep_time
sleep(sleep_time)

View File

@ -1,101 +0,0 @@
commit 95ba9053e20ad8d113af37b3f1f4cbfff1f6a8f1
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed Jul 7 10:38:10 2021 +0000
Fix StartTLS stripping vulnerability
Reported by Alexandr Savca in https://hackerone.com/reports/1178562
Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67950 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 1c7e89ba14..91df89b79e 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1213,12 +1213,14 @@ def get_tagged_response(tag, cmd)
end
resp = @tagged_responses.delete(tag)
case resp.name
+ when /\A(?:OK)\z/ni
+ return resp
when /\A(?:NO)\z/ni
raise NoResponseError, resp
when /\A(?:BAD)\z/ni
raise BadResponseError, resp
else
- return resp
+ raise UnknownResponseError, resp
end
end
@@ -3714,6 +3716,10 @@ class BadResponseError < ResponseError
class ByeResponseError < ResponseError
end
+ # Error raised upon an unknown response from the server.
+ class UnknownResponseError < ResponseError
+ end
+
RESPONSE_ERRORS = Hash.new(ResponseError)
RESPONSE_ERRORS["NO"] = NoResponseError
RESPONSE_ERRORS["BAD"] = BadResponseError
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
index 936f4e0f42..81928cb8fe 100644
--- a/test/net/imap/test_imap.rb
+++ b/test/net/imap/test_imap.rb
@@ -127,6 +127,24 @@ def test_starttls
imap.disconnect
end
end
+
+ def test_starttls_stripping
+ starttls_stripping_test do |port|
+ imap = Net::IMAP.new("localhost", :port => port)
+ assert_raise(Net::IMAP::UnknownResponseError) do
+ imap.starttls(:ca_file => CA_FILE)
+ end
+ imap
+ end
+ end
+ end
+
+ def start_server
+ th = Thread.new do
+ yield
+ end
+ @threads << th
+ sleep 0.1 until th.stop?
end
def test_unexpected_eof
@@ -760,6 +760,27 @@ def starttls_test
end
end
+ def starttls_stripping_test
+ server = create_tcp_server
+ port = server.addr[1]
+ start_server do
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+ sock.print("RUBY0001 BUG unhandled command\r\n")
+ ensure
+ sock.close
+ server.close
+ end
+ end
+ begin
+ imap = yield(port)
+ ensure
+ imap.disconnect if imap && !imap.disconnected?
+ end
+ end
+
def create_tcp_server
return TCPServer.new(server_addr, 0)
end

View File

@ -1,88 +0,0 @@
commit fe3c49c9baeeab58304ede915b7edd18ecf360fc
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sat Jul 3 17:10:28 2021 +0000
merge revision(s) b1c73f23,c9ab8fe2: [Backport #17877]
[ruby/rdoc] Use File.open to fix the OS Command Injection vulnerability in CVE-2021-31799
https://github.com/ruby/rdoc/commit/a7f5d6ab88
The test for command injection on Unix platforms should be omitted on Windows
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
index ca2c1abefd..46aace7839 100644
--- a/lib/rdoc/rdoc.rb
+++ b/lib/rdoc/rdoc.rb
@@ -436,7 +436,7 @@ def remove_unparseable files
files.reject do |file|
file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or
(file =~ /tags$/i and
- open(file, 'rb') { |io|
+ File.open(file, 'rb') { |io|
io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/
})
end
--- a/lib/rdoc/encoding.rb 2022-02-16 16:51:28.080178281 +0100
+++ b/lib/rdoc/encoding.rb 2022-02-16 16:51:37.108160840 +0100
@@ -18,7 +18,7 @@
# unknown character in the target encoding will be replaced with '?'
def self.read_file filename, encoding, force_transcode = false
- content = open filename, "rb" do |f| f.read end
+ content = File.open filename, "rb" do |f| f.read end
content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/
utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
--- a/lib/rdoc/parser.rb 2021-04-05 13:46:35.000000000 +0200
+++ b/lib/rdoc/parser.rb 2022-02-16 15:37:17.904822389 +0100
@@ -74,7 +74,12 @@
def self.binary?(file)
return false if file =~ /\.(rdoc|txt)$/
- s = File.read(file, 1024) or return false
+ begin
+ open_file = File.open(file)
+ s = open_file.read(1024) or return false
+ ensure
+ open_file.close if open_file
+ end
return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00")
@@ -92,7 +97,8 @@
# http://www.garykessler.net/library/file_sigs.html
def self.zip? file
- zip_signature = File.read file, 4
+ zip_signature = ''
+ File.open(file) { |f| zip_signature = f.read(4) }
zip_signature == "PK\x03\x04" or
zip_signature == "PK\x05\x06" or
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index 3bce54b243..123b1a4f87 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -366,6 +366,18 @@ def test_remove_unparseable_tags_vim
end
end
+ def test_remove_unparseable_CVE_2021_31799
+ skip 'for Un*x platforms' if Gem.win_platform?
+ temp_dir do
+ file_list = ['| touch evil.txt && echo tags']
+ file_list.each do |f|
+ FileUtils.touch f
+ end
+ assert_equal file_list, @rdoc.remove_unparseable(file_list)
+ assert_equal file_list, Dir.children('.')
+ end
+ end
+
def test_setup_output_dir
Dir.mktmpdir {|d|
path = File.join d, 'testdir'

View File

@ -1,42 +0,0 @@
From e2c0652dff671dc6e16a80887e781edc0abc8454 Mon Sep 17 00:00:00 2001
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 24 Nov 2021 11:41:55 +0000
Subject: [PATCH 2/2] When parsing cookies, only decode the values
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67953 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
lib/cgi/cookie.rb | 1 -
test/cgi/test_cgi_cookie.rb | 5 +++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index a2155edb77..009566bb92 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -165,7 +165,6 @@ def self.parse(raw_cookie)
raw_cookie.split(/;\s?/).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
- name = CGI.unescape(name)
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
index 115a57e4a1..985cc0d7a1 100644
--- a/test/cgi/test_cgi_cookie.rb
+++ b/test/cgi/test_cgi_cookie.rb
@@ -101,6 +101,11 @@ def test_cgi_cookie_parse
end
end
+ def test_cgi_cookie_parse_not_decode_name
+ cookie_str = "%66oo=baz;foo=bar"
+ cookies = CGI::Cookie.parse(cookie_str)
+ assert_equal({"%66oo" => ["baz"], "foo" => ["bar"]}, cookies)
+ end
def test_cgi_cookie_arrayinterface
cookie = CGI::Cookie.new('name1', 'a', 'b', 'c')
--
2.36.1

View File

@ -1,918 +0,0 @@
From d5753ec513fa5a4bdcf59fa298642fd0d3a3c364 Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@ruby-lang.org>
Date: Fri, 12 Nov 2021 12:11:13 +0900
Subject: [PATCH 1/2] Add length limit option for methods that parses date
strings
This patch fixes CVE-2021-41817 and created from the commit
<https://github.com/ruby/date/commit/4f9b8e946ba98f0a1774f8e677baa4a45637ebb3>.
We didn't merge the files included in the original commit below, as those are
for rebasing date gem version.
* ext/date/date.gemspec
* ext/date/lib/date.rb
== Original commit message ==
`Date.parse` now raises an ArgumentError when a given date string is
longer than 128. You can configure the limit by giving `limit` keyword
arguments like `Date.parse(str, limit: 1000)`. If you pass `limit: nil`,
the limit is disabled.
Not only `Date.parse` but also the following methods are changed.
* Date._parse
* Date.parse
* DateTime.parse
* Date._iso8601
* Date.iso8601
* DateTime.iso8601
* Date._rfc3339
* Date.rfc3339
* DateTime.rfc3339
* Date._xmlschema
* Date.xmlschema
* DateTime.xmlschema
* Date._rfc2822
* Date.rfc2822
* DateTime.rfc2822
* Date._rfc822
* Date.rfc822
* DateTime.rfc822
* Date._jisx0301
* Date.jisx0301
* DateTime.jisx0301
---
ext/date/date_core.c | 384 +++++++++++++++++++++++++++--------
test/date/test_date_parse.rb | 29 +++
2 files changed, 325 insertions(+), 88 deletions(-)
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index c250633426..177ea0f6c5 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -4290,12 +4290,37 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
VALUE date__parse(VALUE str, VALUE comp);
+static size_t
+get_limit(VALUE opt)
+{
+ if (!NIL_P(opt)) {
+ VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
+ if (NIL_P(limit)) return SIZE_MAX;
+ return NUM2SIZET(limit);
+ }
+ return 128;
+}
+
+static void
+check_limit(VALUE str, VALUE opt)
+{
+ StringValue(str);
+ size_t slen = RSTRING_LEN(str);
+ size_t limit = get_limit(opt);
+ if (slen > limit) {
+ rb_raise(rb_eArgError,
+ "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
+ }
+}
+
static VALUE
date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
{
- VALUE vstr, vcomp, hash;
+ VALUE vstr, vcomp, hash, opt;
- rb_scan_args(argc, argv, "11", &vstr, &vcomp);
+ rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
+ if (!NIL_P(opt)) argc--;
+ check_limit(vstr, opt);
StringValue(vstr);
if (!rb_enc_str_asciicompat_p(vstr))
rb_raise(rb_eArgError,
@@ -4320,7 +4345,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * Date._parse(string[, comp=true]) -> hash
+ * Date._parse(string[, comp=true], limit: 128) -> hash
*
* Parses the given representation of date and time, and returns a
* hash of parsed elements. This method does not function as a
@@ -4331,6 +4356,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
* it full.
*
* Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
@@ -4340,7 +4369,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date
+ * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128) -> date
*
* Parses the given representation of date and time, and creates a
* date object. This method does not function as a validator.
@@ -4352,13 +4381,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
* Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
* Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
* Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_parse(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, comp, sg;
+ VALUE str, comp, sg, opt;
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4370,11 +4404,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE argv2[2], hash;
-
- argv2[0] = str;
- argv2[1] = comp;
- hash = date_s__parse(2, argv2, klass);
+ int argc2 = 2;
+ VALUE argv2[3];
+ argv2[0] = str;
+ argv2[1] = comp;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__parse(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
@@ -4388,19 +4423,28 @@ VALUE date__jisx0301(VALUE);
/*
* call-seq:
- * Date._iso8601(string) -> hash
+ * Date._iso8601(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__iso8601(VALUE klass, VALUE str)
+date_s__iso8601(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__iso8601(str);
}
/*
* call-seq:
- * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical ISO 8601 formats.
@@ -4408,13 +4452,18 @@ date_s__iso8601(VALUE klass, VALUE str)
* Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
* Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
* Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4424,38 +4473,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__iso8601(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._rfc3339(string) -> hash
+ * Date._rfc3339(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__rfc3339(VALUE klass, VALUE str)
+date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__rfc3339(str);
}
/*
* call-seq:
- * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date
+ * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical RFC 3339 formats.
*
* Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4465,38 +4532,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc3339(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._xmlschema(string) -> hash
+ * Date._xmlschema(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__xmlschema(VALUE klass, VALUE str)
+date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__xmlschema(str);
}
/*
* call-seq:
- * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical XML Schema formats.
*
* Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4506,41 +4591,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__xmlschema(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._rfc2822(string) -> hash
- * Date._rfc822(string) -> hash
+ * Date._rfc2822(string, limit: 128) -> hash
+ * Date._rfc822(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__rfc2822(VALUE klass, VALUE str)
+date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__rfc2822(str);
}
/*
* call-seq:
- * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
- * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
+ * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
+ * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical RFC 2822 formats.
*
* Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
* #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
@@ -4550,39 +4652,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc2822(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._httpdate(string) -> hash
+ * Date._httpdate(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__httpdate(VALUE klass, VALUE str)
+date_s__httpdate(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__httpdate(str);
}
/*
* call-seq:
- * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date
+ * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some RFC 2616 format.
*
* Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
* #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
@@ -4592,38 +4711,56 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__httpdate(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * Date._jisx0301(string) -> hash
+ * Date._jisx0301(string, limit: 128) -> hash
*
* Returns a hash of parsed elements.
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
-date_s__jisx0301(VALUE klass, VALUE str)
+date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
{
+ VALUE str, opt;
+
+ rb_scan_args(argc, argv, "1:", &str, &opt);
+ check_limit(str, opt);
+
return date__jisx0301(str);
}
/*
* call-seq:
- * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date
+ * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
*
* Creates a new Date object by parsing from a string according to
* some typical JIS X 0301 formats.
*
* Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -4633,7 +4770,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__jisx0301(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
@@ -7925,7 +8066,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
/*
* call-seq:
- * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime
+ * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime
*
* Parses the given representation of date and time, and creates a
* DateTime object. This method does not function as a validator.
@@ -7939,13 +8080,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
* DateTime.parse('3rd Feb 2001 04:05:06 PM')
* #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, comp, sg;
+ VALUE str, comp, sg, opt;
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -7957,18 +8103,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE argv2[2], hash;
-
- argv2[0] = str;
- argv2[1] = comp;
- hash = date_s__parse(2, argv2, klass);
+ int argc2 = 2;
+ VALUE argv2[3];
+ argv2[0] = str;
+ argv2[1] = comp;
+ argv2[2] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__parse(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical ISO 8601 formats.
@@ -7979,13 +8127,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
* DateTime.iso8601('2001-W05-6T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -7995,27 +8148,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__iso8601(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2--;
+ VALUE hash = date_s__iso8601(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical RFC 3339 formats.
*
* DateTime.rfc3339('2001-02-03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8025,27 +8188,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc3339(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__rfc3339(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical XML Schema formats.
*
* DateTime.xmlschema('2001-02-03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8055,28 +8228,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__xmlschema(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__xmlschema(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
- * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
+ * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
+ * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical RFC 2822 formats.
*
* DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8086,7 +8269,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__rfc2822(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
@@ -8100,13 +8288,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
*
* DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
* #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8116,27 +8309,37 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__httpdate(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__httpdate(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
/*
* call-seq:
- * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
+ * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
*
* Creates a new DateTime object by parsing from a string according to
* some typical JIS X 0301 formats.
*
* DateTime.jisx0301('H13.02.03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
+ *
+ * Raise an ArgumentError when the string length is longer than _limit_.
+ * You can stop this check by passing `limit: nil`, but note that
+ * it may take a long time to parse.
*/
static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
- VALUE str, sg;
+ VALUE str, sg, opt;
- rb_scan_args(argc, argv, "02", &str, &sg);
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
+ if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
@@ -8146,7 +8349,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
{
- VALUE hash = date_s__jisx0301(klass, str);
+ int argc2 = 1;
+ VALUE argv2[2];
+ argv2[0] = str;
+ argv2[1] = opt;
+ if (!NIL_P(opt)) argc2++;
+ VALUE hash = date_s__jisx0301(argc2, argv2, klass);
return dt_new_by_frags(klass, hash, sg);
}
}
@@ -9297,19 +9505,19 @@ Init_date_core(void)
rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1);
rb_define_singleton_method(cDate, "_parse", date_s__parse, -1);
rb_define_singleton_method(cDate, "parse", date_s_parse, -1);
- rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
+ rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1);
- rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
+ rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1);
- rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
+ rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1);
- rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
- rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
+ rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
+ rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1);
rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1);
- rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
+ rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1);
- rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
+ rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
#ifndef NDEBUG
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
index ac0eb85ca7..f9b160ee8c 100644
--- a/test/date/test_date_parse.rb
+++ b/test/date/test_date_parse.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'test/unit'
require 'date'
+require 'timeout'
class TestDateParse < Test::Unit::TestCase
@@ -1122,4 +1123,32 @@ def test_given_string
assert_equal(s0, s)
end
+ def test_length_limit
+ assert_raise(ArgumentError) { Date._parse("1" * 1000) }
+ assert_raise(ArgumentError) { Date._iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { Date._xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { Date._rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { Date._jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { Date.parse("1" * 1000) }
+ assert_raise(ArgumentError) { Date.iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { Date.xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { Date.rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { Date.jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { DateTime.parse("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.iso8601("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc3339("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.xmlschema("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc2822("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.rfc822("1" * 1000) }
+ assert_raise(ArgumentError) { DateTime.jisx0301("1" * 1000) }
+
+ assert_raise(ArgumentError) { Date._parse("Jan " + "9" * 1000000) }
+ assert_raise(Timeout::Error) { Timeout.timeout(1) { Date._parse("Jan " + "9" * 1000000, limit: nil) } }
+ end
end
--
2.36.1

View File

@ -1,328 +0,0 @@
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

View File

@ -1,52 +0,0 @@
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

View File

@ -1,41 +0,0 @@
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

View File

@ -1,25 +0,0 @@
From a267a40be7844224c5f000530bd3e8e906f1acea Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@jeremyevans.net>
Date: Wed, 10 Mar 2021 13:48:00 -0800
Subject: [PATCH] Do not use a libdir for glibc, it breaks Linux PPC64 (#70)
Fixes [Bug #12666]
---
test/fiddle/helper.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
index f38f903..a6e2019 100644
--- a/test/fiddle/helper.rb
+++ b/test/fiddle/helper.rb
@@ -20,8 +20,8 @@
# 64-bit ruby
libdir = '/lib64' if File.directory? '/lib64'
end
- libc_so = File.join(libdir, "libc.so.6")
- libm_so = File.join(libdir, "libm.so.6")
+ libc_so = "libc.so.6"
+ libm_so = "libm.so.6"
when /mingw/, /mswin/
require "rbconfig"
crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'

View File

@ -1,70 +0,0 @@
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

View File

@ -1,27 +0,0 @@
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'

View File

@ -1,41 +0,0 @@
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')

View File

@ -21,7 +21,7 @@
%endif
%global release 111
%global release 107
%{!?release_string:%global release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
@ -75,7 +75,7 @@
Summary: An interpreter of object-oriented scripting language
Name: ruby
Version: %{ruby_version}
Release: %{release_string}
Release: %{release_string}.alma
Group: Development/Languages
# Public Domain for example for: include/ruby/st.h, strftime.c, missing/*, ...
# MIT and CCO: ccan/*
@ -103,8 +103,8 @@ Source14: test_systemtap.rb
# The load directive is supported since RPM 4.12, i.e. F21+. The build process
# fails on older Fedoras.
%{load:%{SOURCE4}}
%{load:%{SOURCE5}}
%{?load:%{SOURCE4}}
%{?load:%{SOURCE5}}
# Fix ruby_version abuse.
# https://bugs.ruby-lang.org/issues/11002
@ -130,9 +130,10 @@ Patch6: ruby-2.1.0-Allow-to-specify-additional-preludes-by-configuratio.patch
# Use miniruby to regenerate prelude.c.
# https://bugs.ruby-lang.org/issues/10554
Patch7: ruby-2.2.3-Generate-preludes-using-miniruby.patch
# Fix a fiddle import test on an optimized glibc on Power 9.
# https://bugs.ruby-lang.org/issues/12666#note-13
Patch9: ruby-3.0.3-fiddle-1.0.8-Rely-on-hard-coded-lib-name-to-detect-glibc.patch
# Workaround "an invalid stdio handle" error on PPC, due to recently introduced
# hardening features of glibc (rhbz#1361037).
# https://bugs.ruby-lang.org/issues/12666
Patch9: ruby-2.3.1-Rely-on-ldd-to-detect-glibc.patch
# Add Gem.operating_system_defaults to allow packagers to override defaults.
# https://github.com/rubygems/rubygems/pull/2116
Patch10: ruby-2.5.0-Add-Gem.operating_system_defaults.patch
@ -175,62 +176,11 @@ Patch27: ruby-2.6.0-rdoc-6.0.2-fix-different-js-gz-pages-across-multilib.patch
Patch28: ruby-2.5.9-revert-stop-the-error-due-to-openssl-1-1-1h.patch
# Resolv::DNS: timeouts if multiple IPv6 name servers are given and address
# contains leading zero
# https://bugzilla.redhat.com/show_bug.cgi?id=1950308
# https://bugzilla.redhat.com/show_bug.cgi?id=1955010
Patch29: ruby-3.0.0-Convert-ip-addresses-to-canonical-form.patch
# Fix CVE-2021-31799 rdoc: Command injection vulnerability in RDoc.
# https://bugzilla.redhat.com/show_bug.cgi?id=1980839
Patch30: ruby-2.6.8-rdoc-6.1.2.1-command-injection-vulnerability.patch
# Fix CVE-2021-32066 StartTLS stripping vulnerability in Net::IMAP.
# https://bugzilla.redhat.com/show_bug.cgi?id=1980830
Patch31: ruby-2.6.8-net-imap-startls-stripping-vulnerability.patch
# Fix CVE-2021-31810 FTP PASV command response can cause Net::FTP to connect
# to arbitrary host.
# https://bugzilla.redhat.com/show_bug.cgi?id=1980825
Patch32: ruby-2.6.8-net-ftp-pasv-can-connect-to-arbitrary-host.patch
# CVE-2021-41817: Fix by adding a length limit option for methods that parses
# date strings.
# https://bugzilla.redhat.com/show_bug.cgi?id=2025104
# https://github.com/ruby/date/commit/4f9b8e946ba98f0a1774f8e677baa4a45637ebb3
Patch33: ruby-2.6.9-date-2.0.1-parse-length-limit.patch
# CVE-2021-41819: CGI::Cookie.parse that no longer decodes cookie names to
# prevent spoofing security prefixes in cookie names.
# https://bugzilla.redhat.com/show_bug.cgi?id=2026757
# https://github.com/ruby/ruby/commit/02c341c9bc5879eae568ed2ba02cf227ed948199
# https://github.com/ruby/cgi/commit/84dedc6fbb2a210ec070c35bc607b89003701fa2
Patch34: ruby-2.6.9-cgi-0.1.1-cookie-parse-not-decode-names.patch
# Fix rdoc nil token parsing
# https://github.com/ruby/rdoc/commit/a1631aa98a67112d96ac101c72909fdeec6f84f9
Patch35: ruby-2.6.0-rdoc-6.0.2-check-nil-text-token.patch
# Fix Time Zone Database 2022g.
# https://bugs.ruby-lang.org/issues/19187
# https://github.com/ruby/ruby/commit/a1124dc162810f86cb0bff58cde24064cfc561bc
Patch36: ruby-3.1.3-Fix-for-tzdata-2022g.patch
# Bypass git submodule test failure on Git >= 2.38.1.
# https://github.com/ruby/ruby/pull/6587
Patch37: ruby-3.2.0-git-2.38.1-fix-rubygems-test.patch
# CVE-2021-33621: HTTP response splitting in CGI.
# Backported from:
# https://github.com/ruby/ruby/commit/7cf697179dab52b0d024543304f4d3ab5fa5e847
Patch38: ruby-2.7.7-Fix-CVE-2021-33621-HTTP-response-splitting-in-CGI.patch
# Let cookies use leading dot in the domain after fixing CVE-2021-33621
# to retain compatibility.
# https://github.com/ruby/cgi/commit/5e09d632f3b56d85b2659ab47d5571ae9e270e10
Patch39: rubygem-cgi-0.3.6-Loosen-the-domain-regex-to-accept-dot.patch
# CVE-2022-28739: Buffer overrun in String-to-Float conversion.
# Backported from:
# https://github.com/ruby/ruby/commit/69f9992ed41920389d4185141a14f02f89a4d306
Patch40: ruby-2.6.10-Fix-CVE-2022-28739-Buffer-overrun-in-str2float.patch
# CVE-2023-28755 ReDoS vulnerability in URI.
# Backported from:
# https://github.com/ruby/ruby/commit/6855779d580358a6a0b4c9ee06f20e7cae72955a
Patch41: ruby-2.7.8-Fix-CVE-2023-28755-ReDos-vulnerability-in-URI.patch
# CVE-2023-28756 ReDoS vulnerability in Time.
# Tests not included as assert_linear_time was introduced in Ruby 2.7.
# Backported from:
# https://github.com/ruby/ruby/commit/2cb830602f52e7e76c6781115e7938b21f881c4f
# https://github.com/ruby/ruby/commit/e3f18f7d2e034f20053d7bf2fc7a50f8b7e1a27a
Patch42: ruby-2.7.8-Fix-CVE-2023-28756-ReDoS-vulnerability-in-Time.patch
# AlmaLinux
Patch100: ruby-2.5.9-skip-test_execopts_gid.patch
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Suggests: rubypick
@ -630,19 +580,9 @@ sed -i 's/"evaluation\/incorrect_words.yaml"\.freeze, //' \
%patch27 -p1
%patch28 -p1 -R
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%ifarch aarch64
%patch100 -p1
%endif
# Provide an example of usage of the tapset:
cp -a %{SOURCE3} .
@ -1195,48 +1135,16 @@ OPENSSL_SYSTEM_CIPHERS_OVERRIDE=xyz_nonexistent_file OPENSSL_CONF='' \
%{gem_dir}/specifications/xmlrpc-%{xmlrpc_version}.gemspec
%changelog
* Mon Jun 12 2023 Jarek Prokop <jprokop@redhat.com> - 2.5.9-111
- Fix HTTP response splitting in CGI.
Resolves: CVE-2021-33621
- Fix Buffer overrun in String-to-Float conversion.
Resolves: CVE-2022-28739
- Fix ReDoS vulnerability in URI.
Resolves: CVE-2023-28755
- Fix ReDoS vulnerability in Time.
Resolves: CVE-2023-28756
* Thu May 25 2023 Todd Zullinger <tmz@pobox.com> - 2.5.9-111
- Fix rdoc parsing of nil text tokens.
Resolves: rhbz#2210326
* Fri Jul 08 2022 Jun Aruga <jaruga@redhat.com> - 2.5.9-110
- Fix FTBFS due to an incompatible load directive.
- Fix a fiddle import test on an optimized glibc on Power 9.
- Fix by adding length limit option for methods that parses date strings.
Resolves: CVE-2021-41817
- CGI::Cookie.parse no longer decodes cookie names to prevent spoofing security
prefixes in cookie names.
Resolves: CVE-2021-41819
* Wed Feb 16 2022 Jarek Prokop <jprokop@redhat.com> - 2.5.9-109
- Properly fix command injection vulnerability in Rdoc.
Related: CVE-2021-31799
* Wed Feb 09 2022 Jarek Prokop <jprokop@redhat.com> - 2.5.9-108
- Fix command injection vulnerability in RDoc.
Resolves: CVE-2021-31799
- Fix StartTLS stripping vulnerability in Net::IMAP
Resolves: CVE-2021-32066
- Fix FTP PASV command response can cause Net::FTP to connect to arbitrary host.
Resolves: CVE-2021-31810
* Wed Jul 07 2021 Sergey Fokin <sfokin@cloudlinux.com> - 2.5.9-107.alma
- skip test_execopts_gid for ARM64
* Mon Apr 19 2021 Pavel Valena <pvalena@redhat.com> - 2.5.9-107
- Update to Ruby 2.5.9.
* Remove Patch20: ruby-2.6.0-rdoc-6.0.1-fix-template-typo.patch; subsumed
Resolves: rhbz#1757844
Resolves: rhbz#1952626
- Resolv::DNS: timeouts if multiple IPv6 name servers are given and address
contains leading zero
Resolves: rhbz#1950308
Resolves: rhbz#1955010
* Mon Jun 22 2020 Pavel Valena <pvalena@redhat.com> - 2.5.5-106
- Remove file with non-commercial license from did_you_mean gem.