upgrade to version 3.0.3

(cherry picked from commit bc7aded297480dfc695be96976c37de993ac54af)
This commit is contained in:
shangyibin 2021-12-30 18:46:48 +08:00 committed by openeuler-sync-bot
parent c8f9599e54
commit 19f2a0f560
53 changed files with 10099 additions and 2695 deletions

View File

@ -1,56 +0,0 @@
From 4097828d7cc87589864fecf452f2cd46c5f37180 Mon Sep 17 00:00:00 2001
From: "K.Kosako" <kosako@sofnec.co.jp>
Date: Mon, 29 Jul 2019 12:52:56 +0900
Subject: [PATCH] fix #147: Stack Exhaustion Problem caused by some parsing
functions in regcomp.c making recursive calls to themselves.
---
regparse.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/regparse.c b/regparse.c
index f7177db..c07fccd 100644
--- a/regparse.c
+++ b/regparse.c
@@ -4568,6 +4568,7 @@ parse_char_class(Node** np, Node** asc_np, OnigToken* tok, UChar** src, UChar* e
env->parse_depth++;
if (env->parse_depth > ParseDepthLimit)
return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
+
prev_cc = asc_prev_cc = (CClassNode* )NULL;
r = fetch_token_in_cc(tok, src, end, env);
if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
@@ -6514,14 +6515,18 @@ static int
parse_exp(Node** np, OnigToken* tok, int term,
UChar** src, UChar* end, ScanEnv* env)
{
- int r, len, group = 0;
+ int r, len, group;
Node* qn;
Node** targetp;
+ unsigned int parse_depth;
+ group = 0;
*np = NULL;
if (tok->type == (enum TokenSyms )term)
goto end_of_token;
+ parse_depth = env->parse_depth;
+
switch (tok->type) {
case TK_ALT:
case TK_EOT:
@@ -6832,6 +6837,10 @@ parse_exp(Node** np, OnigToken* tok, int term,
if (is_invalid_quantifier_target(*targetp))
return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
+ parse_depth++;
+ if (parse_depth > ParseDepthLimit)
+ return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
+
qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
(r == TK_INTERVAL ? 1 : 0));
CHECK_NULL_RETURN_MEMERR(qn);
--
1.8.3.1

View File

@ -1,23 +0,0 @@
From 6eb4aca6a7f2f60f473580576d86686ed6a6ebec Mon Sep 17 00:00:00 2001
From: "K.Kosako" <kosako@sofnec.co.jp>
Date: Wed, 6 Nov 2019 17:32:29 +0900
Subject: [PATCH] fix #162: heap-buffer-overflow in fetch_interval_quantifier
due to double PFETCH
---
regparse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/regparse.c b/regparse.c
index 324c414..70c36d5 100644
--- a/regparse.c
+++ b/regparse.c
@@ -4178,7 +4178,7 @@ fetch_interval_quantifier(UChar** src, UChar* end, PToken* tok, ScanEnv* env)
if (PEND) goto invalid;
PFETCH(c);
if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
- if (c != MC_ESC(env->syntax)) goto invalid;
+ if (c != MC_ESC(env->syntax) || PEND) goto invalid;
if (PEND) goto invalid;
PFETCH(c);
}

View File

@ -1,24 +0,0 @@
From d3e402928b6eb3327f8f7d59a9edfa622fec557b Mon Sep 17 00:00:00 2001
From: "K.Kosako" <kosako@sofnec.co.jp>
Date: Tue, 13 Aug 2019 13:37:30 +0900
Subject: [PATCH] fix heap-buffer-overflow
---
regexec.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/regexec.c b/regexec.c
index 4582c35..8a17ee7 100644
--- a/regexec.c
+++ b/regexec.c
@@ -3255,6 +3255,7 @@ str_lower_case_match(OnigEncoding enc, int case_fold_flag,
lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
q = lowbuf;
while (lowlen > 0) {
+ if (t >= tend) return 0;
if (*t++ != *q++) return 0;
lowlen--;
}
--
1.8.3.1

View File

@ -1,35 +0,0 @@
From 8946bb38b4d87549f0d99ed73c62c41933f97cc7 Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@ruby-lang.org>
Date: Tue, 29 Sep 2020 13:15:58 +0900
Subject: [PATCH] Make it more strict to interpret some headers
Some regexps were too tolerant.
---
lib/webrick/httprequest.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb
index 294bd91..d34eac7 100644
--- a/lib/webrick/httprequest.rb
+++ b/lib/webrick/httprequest.rb
@@ -227,9 +227,9 @@ def parse(socket=nil)
raise HTTPStatus::BadRequest, "bad URI `#{@unparsed_uri}'."
end
- if /close/io =~ self["connection"]
+ if /\Aclose\z/io =~ self["connection"]
@keep_alive = false
- elsif /keep-alive/io =~ self["connection"]
+ elsif /\Akeep-alive\z/io =~ self["connection"]
@keep_alive = true
elsif @http_version < "1.1"
@keep_alive = false
@@ -508,7 +508,7 @@ def read_body(socket, block)
return unless socket
if tc = self['transfer-encoding']
case tc
- when /chunked/io then read_chunked(socket, block)
+ when /\Achunked\z/io then read_chunked(socket, block)
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
end
elsif self['content-length'] || @remaining_size

View File

@ -1,36 +0,0 @@
# ruby
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +0,0 @@
# ruby
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,51 +0,0 @@
From a7f5d6ab88632b3b482fe10611382ff73d14eed7 Mon Sep 17 00:00:00 2001
From: aycabta <aycabta@gmail.com>
Date: Sun, 2 May 2021 20:52:23 +0900
Subject: [PATCH] Use File.open to fix the OS Command Injection vulnerability
in CVE-2021-31799
Reference:https://github.com/ruby/rdoc/commit/a7f5d6ab88632b3b482fe10611382ff73d14eed7
---
lib/rdoc/rdoc.rb | 2 +-
test/rdoc/test_rdoc_rdoc.rb | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
index 68775c8..0095eb7 100644
--- a/lib/rdoc/rdoc.rb
+++ b/lib/rdoc/rdoc.rb
@@ -433,7 +433,7 @@ The internal error was:
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
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index bd47943..07541df 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -366,6 +366,18 @@ class TestRDocRDoc < RDoc::TestCase
end
end
+ def test_remove_unparseable_CVE_2021_31799
+ 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'
--
1.8.3.1

View File

@ -1,248 +0,0 @@
From 5709ece67cf57a94655e34532f8a7899b28d496a Mon Sep 17 00:00:00 2001l/pkcs5.
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Wed, 7 Jul 2021 16:00:45 +0900/pkey.rb
Subject: [PATCH] This fixes CVE-2021-31810. Reported by Alexandr Savca inssl.rb
<https://hackerone.com/reports/1145454>./x509.rb
Reference:https://github.com/ruby/net-ftp/commit/5709ece67cf57a94655e34532f8a7899b28d496a
---
lib/net/ftp.rb | 15 ++++-
test/net/ftp/test_ftp.rb | 159 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 170 insertions(+), 4 deletions(-)
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index 9902f9d..cd446b4 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -97,6 +97,10 @@ module Net
# 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 @@ module Net
# 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 @@ module Net
@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 @@ module Net
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 8e0a688..52fb3a9 100644
--- a/test/net/ftp/test_ftp.rb
+++ b/test/net/ftp/test_ftp.rb
@@ -61,7 +61,7 @@ class FTPTest < Test::Unit::TestCase
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 @@ class FTPTest < Test::Unit::TestCase
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 @@ EOF
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)
--
1.8.3.1

View File

@ -1,95 +0,0 @@
From adba6f0c3e5c5607c4822b9120322eb7e9a77891 Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Wed, 7 Jul 2021 16:09:03 +0900
Subject: [PATCH] This fixes CVE-2021-32066. Reported by Alexandr Savca in
<https://hackerone.com/reports/1178562>.
Reference:https://github.com/ruby/net-imap/commit/adba6f0c3e5c5607c4822b9120322eb7e9a77891
---
lib/net/imap.rb | 8 +++++++-
test/net/imap/test_imap.rb | 31 +++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index da7d0d5..eedcb4f 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1213,12 +1213,14 @@ module Net
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 @@ module Net
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 41f25fe..9247062 100644
--- a/test/net/imap/test_imap.rb
+++ b/test/net/imap/test_imap.rb
@@ -110,6 +110,16 @@ class IMAPTest < Test::Unit::TestCase
end
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
if defined?(OpenSSL::SSL)
@@ -760,6 +770,27 @@ EOF
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
--
1.8.3.1

View File

@ -9,6 +9,7 @@
%gem_cache %{gem_dir}/cache/%{gem_name}-%{version}%{?prerelease}.gem %gem_cache %{gem_dir}/cache/%{gem_name}-%{version}%{?prerelease}.gem
%gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}%{?prerelease}.gemspec %gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}%{?prerelease}.gemspec
%gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}%{?prerelease} %gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}%{?prerelease}
%gem_plugin %{gem_dir}/plugins/%{gem_name}_plugin.rb
# %gem_install - Install gem into appropriate directory. # %gem_install - Install gem into appropriate directory.
@ -21,7 +22,7 @@
%gem_install(d:n:) \ %gem_install(d:n:) \
mkdir -p %{-d*}%{!?-d:.%{gem_dir}} \ mkdir -p %{-d*}%{!?-d:.%{gem_dir}} \
\ \
CONFIGURE_ARGS="--with-cflags='%{optflags}' $CONFIGURE_ARGS" \\\ CONFIGURE_ARGS="--with-cflags='%{optflags}' --with-cxxflags='%{optflags}' --with-ldflags='%{build_ldflags}' $CONFIGURE_ARGS" \\\
gem install \\\ gem install \\\
-V \\\ -V \\\
--local \\\ --local \\\
@ -32,16 +33,6 @@ gem install \\\
%{nil} %{nil}
# For rubygems packages we want to filter out any provides caused by private
# libs in %%{gem_archdir}.
#
# Note that this must be invoked in the spec file, preferably as
# "%{?rubygems_default_filter}", before any %description block.
%rubygems_default_filter %{expand: \
%global __provides_exclude_from %{?__provides_exclude_from:%{__provides_exclude_from}|}^%{gem_extdir_mri}/.*\\\\.so$ \
}
# The 'read' command in %%gemspec_* macros is not essential, but it is usefull # The 'read' command in %%gemspec_* macros is not essential, but it is usefull
# to make the sript appear in build log. # to make the sript appear in build log.
@ -60,7 +51,7 @@ gem install \\\
# #
%gemspec_add_dep(g:s:d) \ %gemspec_add_dep(g:s:d) \
read -d '' gemspec_add_dep_script << 'EOR' || : \ read -d '' gemspec_add_dep_script << 'EOR' || : \
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}.gemspec}' \ gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \
\ \
name = '%{-g*}' \ name = '%{-g*}' \
requirements = %{*}%{!?1:nil} \ requirements = %{*}%{!?1:nil} \
@ -97,7 +88,7 @@ unset -v gemspec_add_dep_script \
# #
%gemspec_remove_dep(g:s:d) \ %gemspec_remove_dep(g:s:d) \
read -d '' gemspec_remove_dep_script << 'EOR' || : \ read -d '' gemspec_remove_dep_script << 'EOR' || : \
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}.gemspec}' \ gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \
\ \
name = '%{-g*}' \ name = '%{-g*}' \
requirements = %{*}%{!?1:nil} \ requirements = %{*}%{!?1:nil} \
@ -144,7 +135,7 @@ unset -v gemspec_remove_dep_script \
# #
%gemspec_add_file(s:tr) \ %gemspec_add_file(s:tr) \
read -d '' gemspec_add_file_script << 'EOR' || : \ read -d '' gemspec_add_file_script << 'EOR' || : \
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}.gemspec}' \ gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \
\ \
abort("gemspec_add_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \ abort("gemspec_add_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \
\ \
@ -177,7 +168,7 @@ unset -v gemspec_add_file_script \
# #
%gemspec_remove_file(s:tr) \ %gemspec_remove_file(s:tr) \
read -d '' gemspec_remove_file_script << 'EOR' || : \ read -d '' gemspec_remove_file_script << 'EOR' || : \
gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}.gemspec}' \ gemspec_file = '%{-s*}%{!?-s:%{_builddir}/%{gem_name}-%{version}%{?prerelease}.gemspec}' \
\ \
abort("gemspec_remove_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \ abort("gemspec_remove_file: Use only one '-t' or '-r' at a time.") if "%{?-t}%{?-r}" == "-t-r" \
\ \

View File

@ -119,6 +119,7 @@ module Gem
def default_path def default_path
path = default_dirs.collect {|location, paths| paths[:gem_dir]} path = default_dirs.collect {|location, paths| paths[:gem_dir]}
path.unshift Gem.user_dir if File.exist? Gem.user_home path.unshift Gem.user_dir if File.exist? Gem.user_home
path
end end
def default_ext_dir_for base_dir def default_ext_dir_for base_dir

View File

@ -11,7 +11,7 @@ diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 682eb46..e6b1445 100644 index 682eb46..e6b1445 100644
--- a/lib/mkmf.rb --- a/lib/mkmf.rb
+++ b/lib/mkmf.rb +++ b/lib/mkmf.rb
@@ -1899,7 +1899,7 @@ def configuration(srcdir) @@ -1930,7 +1930,7 @@ def configuration(srcdir)
SHELL = /bin/sh SHELL = /bin/sh
# V=0 quiet, V=1 verbose. other values don't work. # V=0 quiet, V=1 verbose. other values don't work.

View File

@ -1,58 +0,0 @@
From 996012f6abe0ce4d68a2de9f249935c6d5b467bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Fri, 4 Oct 2013 22:13:11 +0200
Subject: [PATCH] Allow to specify addition preludes by configuration option.
---
Makefile.in | 2 ++
common.mk | 2 +-
configure.ac | 7 +++++++
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Makefile.in b/Makefile.in
index 7e8ed82..7916993 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -119,6 +119,8 @@ XRUBY_RUBYLIBDIR = @XRUBY_RUBYLIBDIR@
XRUBY_RUBYHDRDIR = @XRUBY_RUBYHDRDIR@
BOOTSTRAPRUBY = @BOOTSTRAPRUBY@
+OPTIONAL_PRELUDES = @OPTIONAL_PRELUDES@
+
#### End of system configuration section. ####
MAJOR= @MAJOR@
diff --git a/common.mk b/common.mk
index 5cfbc3d..3f0a82e 100644
--- a/common.mk
+++ b/common.mk
@@ -147,7 +147,7 @@ ALLOBJS = $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(INITOBJS)
GOLFOBJS = goruby.$(OBJEXT) golf_prelude.$(OBJEXT)
DEFAULT_PRELUDES = $(GEM_PRELUDE)
-PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(DEFAULT_PRELUDES)
+PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(DEFAULT_PRELUDES) $(OPTIONAL_PRELUDES)
GEM_PRELUDE = $(srcdir)/gem_prelude.rb
PRELUDES = {$(srcdir)}prelude.c {$(srcdir)}miniprelude.c
GOLFPRELUDES = {$(srcdir)}golf_prelude.c
diff --git a/configure.ac b/configure.ac
index 028ef7ca3e..cdeff87871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4396,6 +4396,13 @@ AC_SUBST(rubyarchhdrdir)dnl
AC_SUBST(sitearchhdrdir)dnl
AC_SUBST(vendorarchhdrdir)dnl
+AC_ARG_WITH(prelude,
+ AS_HELP_STRING([--with-prelude=FILE-LIST], [specify additional preludes separated by space]),
+ [prelude=$withval])
+if test "$prelude" != ""; then
+ AC_SUBST(OPTIONAL_PRELUDES, $prelude)
+fi
+
AC_ARG_WITH(mantype,
AS_HELP_STRING([--with-mantype=TYPE], [specify man page type; TYPE is one of man and doc]),
[
--
1.8.3.1

View File

@ -8,10 +8,10 @@ Subject: [PATCH] Allow to configure libruby.so placement.
1 file changed, 5 insertions(+) 1 file changed, 5 insertions(+)
diff --git a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
index 11fc237552..b77e88fc37 100644 index d261ea57b5..3c13076b82 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -3641,6 +3641,11 @@ AS_IF([test ${multiarch+set}], [ @@ -3240,6 +3240,11 @@ AS_IF([test ${multiarch+set}], [
]) ])
archlibdir='${libdir}/${arch}' archlibdir='${libdir}/${arch}'
@ -24,5 +24,5 @@ index 11fc237552..b77e88fc37 100644
archincludedir='${includedir}/${arch}' archincludedir='${includedir}/${arch}'
sitearchincludedir='${includedir}/${sitearch}' sitearchincludedir='${includedir}/${sitearch}'
-- --
1.8.3.1 2.22.0

View File

@ -11,10 +11,10 @@ Subject: [PATCH] Prevent duplicated paths when empty version string is
3 files changed, 15 insertions(+), 2 deletions(-) 3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
index 999e2d6d5d..11fc237552 100644 index c42436c23d..d261ea57b5 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -4251,7 +4251,8 @@ AS_CASE(["$ruby_version_dir_name"], @@ -3881,7 +3881,8 @@ AS_CASE(["$ruby_version_dir_name"],
ruby_version_dir=/'${ruby_version_dir_name}' ruby_version_dir=/'${ruby_version_dir_name}'
if test -z "${ruby_version_dir_name}"; then if test -z "${ruby_version_dir_name}"; then
@ -66,7 +66,7 @@ diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb
index 07076d4..35e6c3c 100755 index 07076d4..35e6c3c 100755
--- a/tool/mkconfig.rb --- a/tool/mkconfig.rb
+++ b/tool/mkconfig.rb +++ b/tool/mkconfig.rb
@@ -111,7 +111,7 @@ @@ -114,7 +114,7 @@
val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump
case name case name
when /^prefix$/ when /^prefix$/

View File

@ -8,10 +8,10 @@ Subject: [PATCH] Always use i386.
1 file changed, 2 insertions(+) 1 file changed, 2 insertions(+)
diff --git a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
index b77e88fc37..6bba453e3c 100644 index 3c13076b82..93af30321d 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -4315,6 +4315,8 @@ AC_SUBST(vendorarchdir)dnl @@ -3945,6 +3945,8 @@ AC_SUBST(vendorarchdir)dnl
AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl
AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl

View File

@ -5,16 +5,17 @@ Subject: [PATCH] Allow to install RubyGems into custom location, outside of
Ruby tree. Ruby tree.
--- ---
configure.ac | 5 +++++ configure.ac | 5 +++++
loadpath.c | 4 ++++ loadpath.c | 4 ++++
template/verconf.h.tmpl | 3 +++ template/verconf.h.tmpl | 3 +++
tool/rbinstall.rb | 7 +++++++ tool/rbinstall.rb | 10 ++++++++++
4 files changed, 19 insertions(+) 4 files changed, 22 insertions(+)
diff -Naur a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
--- a/configure.ac 2020-07-27 16:38:47.589749033 +0800 index 93af30321d..bc13397e0e 100644
+++ b/configure.ac 2020-07-27 16:24:09.948494621 +0800 --- a/configure.ac
@@ -4288,6 +4288,10 @@ +++ b/configure.ac
@@ -3917,6 +3917,10 @@ AC_ARG_WITH(vendorarchdir,
[vendorarchdir=$withval], [vendorarchdir=$withval],
[vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}]) [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}])
@ -25,7 +26,7 @@ diff -Naur a/configure.ac b/configure.ac
AS_IF([test "${LOAD_RELATIVE+set}"], [ AS_IF([test "${LOAD_RELATIVE+set}"], [
AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE)
RUBY_EXEC_PREFIX='' RUBY_EXEC_PREFIX=''
@@ -4312,6 +4316,7 @@ @@ -3941,6 +3945,7 @@ AC_SUBST(sitearchdir)dnl
AC_SUBST(vendordir)dnl AC_SUBST(vendordir)dnl
AC_SUBST(vendorlibdir)dnl AC_SUBST(vendorlibdir)dnl
AC_SUBST(vendorarchdir)dnl AC_SUBST(vendorarchdir)dnl
@ -33,11 +34,11 @@ diff -Naur a/configure.ac b/configure.ac
AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl
AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl
diff --git a/loadpath.c b/loadpath.c
diff -Naur a/loadpath.c b/loadpath.c index 623dc9d..74c5d9e 100644
--- a/loadpath.c 2020-07-27 16:38:47.589749033 +0800 --- a/loadpath.c
+++ b/loadpath.c 2020-07-27 16:24:09.948494621 +0800 +++ b/loadpath.c
@@ -94,6 +94,10 @@ @@ -94,6 +94,10 @@ const char ruby_initial_load_paths[] =
#endif #endif
#endif #endif
@ -48,10 +49,10 @@ diff -Naur a/loadpath.c b/loadpath.c
RUBY_LIB "\0" RUBY_LIB "\0"
#ifdef RUBY_THINARCH #ifdef RUBY_THINARCH
RUBY_ARCH_LIB_FOR(RUBY_THINARCH) "\0" RUBY_ARCH_LIB_FOR(RUBY_THINARCH) "\0"
diff --git a/template/verconf.h.tmpl b/template/verconf.h.tmpl
diff -Naur a/template/verconf.h.tmpl b/template/verconf.h.tmpl index 79c003e..34f2382 100644
--- a/template/verconf.h.tmpl 2020-07-27 16:38:47.589749033 +0800 --- a/template/verconf.h.tmpl
+++ b/template/verconf.h.tmpl 2020-07-27 16:24:09.948494621 +0800 +++ b/template/verconf.h.tmpl
@@ -36,6 +36,9 @@ @@ -36,6 +36,9 @@
% if C["RUBY_SEARCH_PATH"] % if C["RUBY_SEARCH_PATH"]
#define RUBY_SEARCH_PATH "${RUBY_SEARCH_PATH}" #define RUBY_SEARCH_PATH "${RUBY_SEARCH_PATH}"
@ -62,29 +63,35 @@ diff -Naur a/template/verconf.h.tmpl b/template/verconf.h.tmpl
% %
% R = {} % R = {}
% R["ruby_version"] = '"RUBY_LIB_VERSION"' % R["ruby_version"] = '"RUBY_LIB_VERSION"'
diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
diff -Naur a/tool/rbinstall.rb b/tool/rbinstall.rb index e9110a17ca..76a1f0a315 100755
--- a/tool/rbinstall.rb 2020-07-27 16:22:12.328326341 +0800 --- a/tool/rbinstall.rb
+++ b/tool/rbinstall.rb 2020-07-27 16:31:57.009162449 +0800 +++ b/tool/rbinstall.rb
@@ -335,6 +335,7 @@ @@ -349,6 +349,7 @@ def CONFIG.[](name, mandatory = false)
vendorlibdir = CONFIG["vendorlibdir"] vendorlibdir = CONFIG["vendorlibdir"]
vendorarchlibdir = CONFIG["vendorarchdir"] vendorarchlibdir = CONFIG["vendorarchdir"]
end end
+rubygemsdir = CONFIG["rubygemsdir"] +rubygemsdir = CONFIG["rubygemsdir"]
mandir = CONFIG["mandir", true] mandir = CONFIG["mandir", true]
docdir = CONFIG["docdir", true] docdir = CONFIG["docdir", true]
configure_args = Shellwords.shellwords(CONFIG["configure_args"]) enable_shared = CONFIG["ENABLE_SHARED"] == 'yes'
@@ -541,7 +542,13 @@ @@ -581,7 +582,16 @@ def stub
install?(:local, :comm, :lib) do install?(:local, :comm, :lib) do
prepare "library scripts", rubylibdir prepare "library scripts", rubylibdir
noinst = %w[*.txt *.rdoc *.gemspec] noinst = %w[*.txt *.rdoc *.gemspec]
+ noinst += %w[rubygems.rb rubygems/ datadir.rb] if rubygemsdir + # Bundler carries "rubygems.rb" file, so it must be specialcased :/
+ noinst += %w[rubygems.rb rubygems/ bundler.rb bundler/] if rubygemsdir
install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode) install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode)
+ if rubygemsdir + if rubygemsdir
+ noinst = %w[obsolete.rb] + noinst = %w[*.txt *.rdoc *.gemspec]
+ install_recursive(File.join(srcdir, "lib", "rubygems"), File.join(rubygemsdir, "rubygems"), :mode => $data_mode) + install_recursive(File.join(srcdir, "lib", "rubygems"), File.join(rubygemsdir, "rubygems"), :no_install => noinst, :mode => $data_mode)
+ install(File.join(srcdir, "lib", "rubygems.rb"), File.join(rubygemsdir, "rubygems.rb"), :mode => $data_mode) + install(File.join(srcdir, "lib", "rubygems.rb"), File.join(rubygemsdir, "rubygems.rb"), :mode => $data_mode)
+ install_recursive(File.join(srcdir, "lib", "bundler"), File.join(rubylibdir, "bundler"), :no_install => noinst, :mode => $data_mode)
+ install(File.join(srcdir, "lib", "bundler.rb"), rubylibdir, :mode => $data_mode)
+ end + end
end end
install?(:local, :comm, :hdr, :'comm-hdr') do install?(:local, :comm, :hdr, :'comm-hdr') do
--
1.8.3.1

View File

@ -1,28 +0,0 @@
From 07eb5f5e775dec01a92a8b13910eaced9e8ee0cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Tue, 2 Dec 2014 10:56:58 +0100
Subject: [PATCH] Generate preludes using miniruby.
---
common.mk | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/common.mk b/common.mk
index 168dc52..20c218a 100644
--- a/common.mk
+++ b/common.mk
@@ -962,9 +962,9 @@ $(MINIPRELUDE_C): $(COMPILE_PRELUDE)
$(srcdir)/template/prelude.c.tmpl
$(PRELUDE_C): $(COMPILE_PRELUDE) \
- $(PRELUDE_SCRIPTS)
+ $(PRELUDE_SCRIPTS) $(PREP)
$(ECHO) generating $@
- $(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
+ $(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
$(srcdir)/template/prelude.c.tmpl $(PRELUDE_SCRIPTS)
{$(VPATH)}golf_prelude.c: $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb
--
2.6.3

View File

@ -12,15 +12,15 @@ ruby_version_dir_name now specifies custom version string for versioned
directories, e.g. instead of default X.Y.Z, you can specify whatever directories, e.g. instead of default X.Y.Z, you can specify whatever
string. string.
--- ---
configure.ac | 64 ++++++++++++++++++++++++++++------------------------- configure.ac | 64 ++++++++++++++++++++++++---------------------
template/ruby.pc.in | 1 + template/ruby.pc.in | 1 +
2 files changed, 35 insertions(+), 30 deletions(-) 2 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/configure.ac b/configure.ac diff --git a/configure.ac b/configure.ac
index 8ea969412f..a00f2b6776 100644 index 80b137e380..63cd3b4f8b 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -4202,9 +4202,6 @@ AS_CASE(["$target_os"], @@ -3832,9 +3832,6 @@ AS_CASE(["$target_os"],
rubyw_install_name='$(RUBYW_INSTALL_NAME)' rubyw_install_name='$(RUBYW_INSTALL_NAME)'
]) ])
@ -30,7 +30,7 @@ index 8ea969412f..a00f2b6776 100644
rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'} rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'}
AC_ARG_WITH(rubyarchprefix, AC_ARG_WITH(rubyarchprefix,
AS_HELP_STRING([--with-rubyarchprefix=DIR], AS_HELP_STRING([--with-rubyarchprefix=DIR],
@@ -4227,56 +4224,62 @@ AC_ARG_WITH(ridir, @@ -3857,56 +3854,62 @@ AC_ARG_WITH(ridir,
AC_SUBST(ridir) AC_SUBST(ridir)
AC_SUBST(RI_BASE_NAME) AC_SUBST(RI_BASE_NAME)
@ -120,7 +120,7 @@ index 8ea969412f..a00f2b6776 100644
AS_IF([test "${LOAD_RELATIVE+set}"], [ AS_IF([test "${LOAD_RELATIVE+set}"], [
AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE)
@@ -4293,6 +4296,7 @@ AC_SUBST(sitearchincludedir)dnl @@ -3923,6 +3926,7 @@ AC_SUBST(sitearchincludedir)dnl
AC_SUBST(arch)dnl AC_SUBST(arch)dnl
AC_SUBST(sitearch)dnl AC_SUBST(sitearch)dnl
AC_SUBST(ruby_version)dnl AC_SUBST(ruby_version)dnl
@ -165,74 +165,66 @@ index 970cb91..5bf8230 100644
- version = RbConfig::CONFIG['ruby_version'] - version = RbConfig::CONFIG['ruby_version']
+ version = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] + version = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
BASE = if RbConfig::CONFIG.key? 'ridir' then BASE = File.join RbConfig::CONFIG['ridir'], version
File.join RbConfig::CONFIG['ridir'], version
diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
index d4c110e..d39c9a6 100755 index d4c110e..d39c9a6 100755
--- a/tool/rbinstall.rb --- a/tool/rbinstall.rb
+++ b/tool/rbinstall.rb +++ b/tool/rbinstall.rb
@@ -417,7 +417,7 @@ def CONFIG.[](name, mandatory = false) @@ -439,7 +439,7 @@ def CONFIG.[](name, mandatory = false)
install?(:doc, :rdoc) do install?(:doc, :rdoc) do
if $rdocdir if $rdocdir
- ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system") - ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system")
+ ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version_dir_name'] || CONFIG['ruby_version'], "system") + ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version_dir_name'] || CONFIG['ruby_version'], "system")
prepare "rdoc", ridatadir prepare "rdoc", ridatadir
install_recursive($rdocdir, ridatadir, :mode => $data_mode) install_recursive($rdocdir, ridatadir, :no_install => rdoc_noinst, :mode => $data_mode)
end end
-- --
2.1.0 2.23.0
From f8d136f9a46d1fe87eba622ab9665935d05e981b Mon Sep 17 00:00:00 2001 From 9f0ec0233f618cbb862629816b22491c3df79578 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Tue, 31 Mar 2015 16:37:44 +0200 Date: Tue, 31 Mar 2015 16:37:44 +0200
Subject: [PATCH 3/4] Add ruby_version_dir_name support for RubyGems. Subject: [PATCH 3/4] Add ruby_version_dir_name support for RubyGems.
--- ---
lib/rubygems/defaults.rb | 11 ++++++----- lib/rubygems/defaults.rb | 9 +++++----
test/rubygems/test_gem.rb | 5 +++-- test/rubygems/test_gem.rb | 5 +++--
2 files changed, 9 insertions(+), 7 deletions(-) 2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 55ca080..75eea2b 100644 index d4ff4a262c..3f9a5bf590 100644
--- a/lib/rubygems/defaults.rb --- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb
@@ -32,20 +32,20 @@ def self.default_dir @@ -38,13 +38,13 @@ def self.default_dir
[ [
File.dirname(RbConfig::CONFIG['sitedir']), File.dirname(RbConfig::CONFIG['sitedir']),
'Gems', 'Gems',
- RbConfig::CONFIG['ruby_version'] - RbConfig::CONFIG['ruby_version'],
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] + RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
] ]
elsif RbConfig::CONFIG['rubylibprefix'] then
[
RbConfig::CONFIG['rubylibprefix'],
'gems',
- RbConfig::CONFIG['ruby_version']
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
]
else else
[ [
RbConfig::CONFIG['libdir'], RbConfig::CONFIG['rubylibprefix'],
ruby_engine,
'gems', 'gems',
- RbConfig::CONFIG['ruby_version'] - RbConfig::CONFIG['ruby_version'],
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] + RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
] ]
end end
@@ -75,7 +75,8 @@ def self.default_rubygems_dirs @@ -117,7 +117,8 @@ def self.user_dir
gem_dir = File.join(Gem.user_home, ".gem")
def self.user_dir gem_dir = File.join(Gem.data_home, "gem") unless File.exist?(gem_dir)
parts = [Gem.user_home, '.gem', ruby_engine] parts = [gem_dir, ruby_engine]
- parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? - parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty?
+ ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] + ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
+ parts << ruby_version_dir_name unless ruby_version_dir_name.empty? + parts << ruby_version_dir_name unless ruby_version_dir_name.empty?
File.join parts File.join parts
end end
@@ -172,7 +173,7 @@ def self.vendor_dir # :nodoc: @@ -252,7 +253,7 @@ def self.vendor_dir # :nodoc:
return nil unless RbConfig::CONFIG.key? 'vendordir' return nil unless RbConfig::CONFIG.key? 'vendordir'
File.join RbConfig::CONFIG['vendordir'], 'gems', File.join RbConfig::CONFIG['vendordir'], 'gems',
@ -242,10 +234,10 @@ index 55ca080..75eea2b 100644
## ##
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 0428bea..b6e090e 100644 index b25068405d..e9fef4a311 100644
--- a/test/rubygems/test_gem.rb --- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb
@@ -1156,7 +1156,8 @@ def test_self_use_paths @@ -1440,7 +1440,8 @@ def test_self_use_paths
def test_self_user_dir def test_self_user_dir
parts = [@userhome, '.gem', Gem.ruby_engine] parts = [@userhome, '.gem', Gem.ruby_engine]
@ -253,17 +245,17 @@ index 0428bea..b6e090e 100644
+ ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] + ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
+ parts << ruby_version_dir_name unless ruby_version_dir_name.empty? + parts << ruby_version_dir_name unless ruby_version_dir_name.empty?
assert_equal File.join(parts), Gem.user_dir FileUtils.mkdir_p File.join(parts)
end
@@ -1283,7 +1284,7 @@ def test_self_user_home_user_drive_and_path
def test_self_vendor_dir
expected =
File.join RbConfig::CONFIG['vendordir'], 'gems',
- RbConfig::CONFIG['ruby_version']
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
assert_equal expected, Gem.vendor_dir @@ -1516,7 +1517,7 @@ def test_self_vendor_dir
end vendordir(File.join(@tempdir, 'vendor')) do
expected =
File.join RbConfig::CONFIG['vendordir'], 'gems',
- RbConfig::CONFIG['ruby_version']
+ RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
assert_equal expected, Gem.vendor_dir
end
-- --
2.1.0 2.1.0
@ -282,15 +274,15 @@ diff --git a/configure.ac b/configure.ac
index a00f2b6776..999e2d6d5d 100644 index a00f2b6776..999e2d6d5d 100644
--- a/configure.ac --- a/configure.ac
+++ b/configure.ac +++ b/configure.ac
@@ -164,7 +164,7 @@ RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"` @@ -107,7 +107,7 @@ RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"`
RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"` RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"`
AC_SUBST(RUBY_BASE_NAME) AC_SUBST(RUBY_BASE_NAME)
AC_SUBST(RUBYW_BASE_NAME) AC_SUBST(RUBYW_BASE_NAME)
-AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}') -AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}')
+AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version_dir_name}') +AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version_dir_name}')
AC_CANONICAL_TARGET dnl checks for alternative programs
test x"$target_alias" = x && AC_CANONICAL_BUILD
-- --
2.1.0 2.1.0

View File

@ -8,109 +8,23 @@ on Red Hat platforms.
This workaround rhbz#1361037 This workaround rhbz#1361037
--- ---
test/fiddle/helper.rb | 92 --------------------------------------------------- test/fiddle/helper.rb | 3 +++
1 file changed, 92 deletions(-) 1 file changed, 3 insertions(+)
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
index 1da3d93..65148a1 100644 index 1da3d93..65148a1 100644
--- a/test/fiddle/helper.rb --- a/test/fiddle/helper.rb
+++ b/test/fiddle/helper.rb +++ b/test/fiddle/helper.rb
@@ -6,95 +6,6 @@ @@ -139,6 +139,9 @@
libc_so = libm_so = "/usr/lib/libSystem.B.dylib"
end
libc_so = libm_so = nil +# Just ignore the heuristic, because it is not reliable on all platforms.
+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 if !libc_so || !libm_so
ruby = EnvUtil.rubybin ruby = EnvUtil.rubybin
ldd = `ldd #{ruby}` # When the ruby binary is 32-bit and the host is 64-bit,
-- --
2.9.2 2.9.2

View File

@ -1,80 +0,0 @@
From 60eb961c25f801ee43ca1be9393ab2f0a0546677 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Tue, 19 Dec 2017 14:00:20 +0100
Subject: [PATCH] Add Gem.operating_system_defaults to allow packagers to
override defaults.
This change allows Ruby packagers to override defaults and lazily query
them.
This is very much the same change as #1644 to treat the
operating_system defaults the same way as platform defaults.
---
lib/rubygems/config_file.rb | 2 +-
lib/rubygems/defaults.rb | 21 ++++++++++++++++++++-
test/rubygems/test_gem.rb | 7 +++++++
3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
index a4efed0f5a..deee38e6d9 100644
--- a/lib/rubygems/config_file.rb
+++ b/lib/rubygems/config_file.rb
@@ -48,7 +48,7 @@ class Gem::ConfigFile
# For Ruby packagers to set configuration defaults. Set in
# rubygems/defaults/operating_system.rb
- OPERATING_SYSTEM_DEFAULTS = {}
+ OPERATING_SYSTEM_DEFAULTS = Gem.operating_system_defaults
##
# For Ruby implementers to set configuration defaults. Set in
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 43d57fc808..b8222877ae 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -177,7 +177,26 @@ def self.vendor_dir # :nodoc:
end
##
- # Default options for gem commands.
+ # Default options for gem commands for Ruby packagers.
+ #
+ # The options here should be structured as an array of string "gem"
+ # command names as keys and a string of the default options as values.
+ #
+ # Example:
+ #
+ # def self.operating_system_defaults
+ # {
+ # 'install' => '--no-rdoc --no-ri --env-shebang',
+ # 'update' => '--no-rdoc --no-ri --env-shebang'
+ # }
+ # end
+
+ def self.operating_system_defaults
+ {}
+ end
+
+ ##
+ # Default options for gem commands for Ruby implementers.
#
# The options here should be structured as an array of string "gem"
# command names as keys and a string of the default options as values.
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 3225a05c6b..62b80c4945 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -1802,6 +1802,13 @@ def test_use_gemdeps_specific
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
end
+ def test_operating_system_defaults
+ operating_system_defaults = Gem.operating_system_defaults
+
+ assert operating_system_defaults != nil
+ assert operating_system_defaults.is_a? Hash
+ end
+
def test_platform_defaults
platform_defaults = Gem.platform_defaults

View File

@ -1,35 +0,0 @@
From 51e2c91412a511196e58efea5b87c460b4fa6a20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Thu, 26 Jul 2018 13:17:52 +0200
Subject: [PATCH] Avoid need of C++ compiler to pass the test suite.
The test suite fails when C++ compiler is not available on the system:
~~~
TestGemExtCmakeBuilder#test_self_build:
Gem::InstallError: cmake failed, exit code 1
/builddir/build/BUILD/ruby-2.5.1/lib/rubygems/ext/builder.rb:92:in `run'
/builddir/build/BUILD/ruby-2.5.1/lib/rubygems/ext/cmake_builder.rb:10:in `build'
/builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:37:in `block in test_self_build'
/builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:36:in `chdir'
/builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:36:in `test_self_build'
~~~
But there is nothing which would realy required C++. It is just CMake
default to check for C++.
---
test/rubygems/test_gem_ext_cmake_builder.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb
index 76d3cb2afe..2d449fc2fd 100644
--- a/test/rubygems/test_gem_ext_cmake_builder.rb
+++ b/test/rubygems/test_gem_ext_cmake_builder.rb
@@ -25,6 +25,7 @@ def test_self_build
File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists|
cmakelists.write <<-eo_cmake
cmake_minimum_required(VERSION 2.6)
+project(self_build LANGUAGES NONE)
install (FILES test.txt DESTINATION bin)
eo_cmake
end

View File

@ -1,177 +0,0 @@
From bb3db69e2a0c210cc3a63940622db96a97eb7947 Mon Sep 17 00:00:00 2001
From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Fri, 2 Mar 2018 01:37:53 +0000
Subject: [PATCH] configure.ac: library options to MAINLIBS
* configure.ac (MAINLIBS): moved library options for main program
and static libruby, and append MAINLIBS to LIBRUBYARG_STATIC, as
these libraries are not needed for linking to shared libruby.
[ruby-core:85882] [Bug #14422]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
configure.ac | 33 +++++++++++++++------------------
template/ruby.pc.in | 1 +
win32/Makefile.sub | 6 ++++--
3 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/configure.ac b/configure.ac
index aebbae1969a5..733a0c992fd7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,7 @@ AC_DISABLE_OPTION_CHECKING
AC_ARG_VAR([cflags], [additional CFLAGS])
AC_ARG_VAR([cppflags], [additional CPPFLAGS])
AC_ARG_VAR([cxxflags], [additional CXXFLAGS])
+ORIG_LIBS=$LIBS
AC_DEFUN([RUBY_RM_RECURSIVE], [
m4_version_prereq([2.70], [-1], [
@@ -2938,13 +2939,11 @@ AS_IF([test x"$enable_pthread" = xyes], [
AC_DEFINE(_THREAD_SAFE)
AC_DEFINE(HAVE_LIBPTHREAD)
AC_CHECK_HEADERS(pthread_np.h, [], [], [@%:@include <pthread.h>])
- AS_CASE([$pthread_lib],
- [c], [],
- [root], [],
- [c_r], [MAINLIBS="-pthread $MAINLIBS"],
- [AS_CASE(["$target_os"],
- [openbsd*|mirbsd*], [LIBS="-pthread $LIBS"],
- [LIBS="-l$pthread_lib $LIBS"])])
+ AS_CASE(["$pthread_lib:$target_os"],
+ [c:*], [],
+ [root:*], [],
+ [c_r:*|*:openbsd*|*:mirbsd*], [LIBS="-pthread $LIBS"],
+ [LIBS="-l$pthread_lib $LIBS"])
], [
AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled")
])
@@ -3623,7 +3622,7 @@ LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'
LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static'
LIBRUBYARG='$(LIBRUBYARG_STATIC)'
-SOLIBS=
+SOLIBS='$(MAINLIBS)'
AS_CASE(["$target_os"],
[cygwin*|mingw*|haiku*|darwin*], [
@@ -3689,9 +3688,6 @@ AS_CASE("$enable_shared", [yes], [
LIBRUBY_RELATIVE=no
test -z "$CCDLFLAGS" || CFLAGS="$CFLAGS $CCDLFLAGS"
ENABLE_SHARED=yes
- AS_IF([test "$rb_cv_binary_elf" = yes], [
- SOLIBS='$(LIBS)'
- ])
# libdir can be overridden in config.site file (on OpenSUSE at least).
libdir_basename=lib
@@ -3726,7 +3722,6 @@ AS_CASE("$enable_shared", [yes], [
])
],
[freebsd*|dragonfly*], [
- SOLIBS='$(LIBS)'
LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)'
LIBRUBY_SONAME='$(LIBRUBY_SO)'
AS_IF([test "$rb_cv_binary_elf" != "yes" ], [
@@ -3735,7 +3730,6 @@ AS_CASE("$enable_shared", [yes], [
])
],
[netbsd*], [
- SOLIBS='$(LIBS)'
LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)'
LIBRUBY_SO="${LIBRUBY_SONAME}"'.$(TEENY)'
RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"])
@@ -3746,11 +3740,9 @@ AS_CASE("$enable_shared", [yes], [
])
],
[openbsd*|mirbsd*], [
- SOLIBS='$(LIBS)'
LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR).'`expr ${MINOR} \* 10 + ${TEENY}`
],
[solaris*], [
- SOLIBS='$(LIBS)'
LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)'
LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_PROGRAM_VERSION)'
LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)'
@@ -3768,7 +3760,7 @@ AS_CASE("$enable_shared", [yes], [
[aix*], [
RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-bnoentry" "$XLDFLAGS" "$LDFLAGS_OPTDIR"])
LIBRUBYARG_SHARED='-L${libdir} -l${RUBY_SO_NAME}'
- SOLIBS='-lm -lc'
+ LIBS="$LIBS -lm -lc"
],
[darwin*], [
LIBRUBY_LDSHARED='$(CC) -dynamiclib'
@@ -3788,7 +3780,6 @@ AS_CASE("$enable_shared", [yes], [
LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT)'
LIBRUBY_SONAME='lib$(RUBY_BASE_NAME).$(RUBY_API_VERSION).$(SOEXT)'
LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_INSTALL_NAME).$(SOEXT)'
- SOLIBS='$(LIBS)'
],
[interix*], [
LIBRUBYARG_SHARED='-L. -L${libdir} -l$(RUBY_SO_NAME)'
@@ -4031,7 +4022,6 @@ AS_CASE(["$target_os"],
])
LIBRUBY_ALIASES=''
FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in
- SOLIBS='$(LIBS)'
AS_IF([test x"$enable_shared" = xyes], [
LIBRUBY='lib$(RUBY_SO_NAME).dll.a'
], [
@@ -4131,6 +4121,13 @@ AS_IF([test "${universal_binary-no}" = yes ], [
[rb_cv_architecture_available=yes], [rb_cv_architecture_available=no]))
])
+MAINLIBS="$LIBS"
+LIBS=$ORIG_LIBS
+AS_IF([test -n "${LIBS}"], [
+ libspat=`echo "${LIBS}" | sed 's/[[][|.*$^]]/\\&/g;s/^ */ /;s/^ *$/ /'`
+ MAINFLAGS=`echo " $MAINLIBS " | sed "s|$libspat"'||;s/^ *//;s/ *$//'`
+])
+LIBRUBYARG_STATIC="${LIBRUBYARG_STATIC} \$(MAINLIBS)"
CPPFLAGS="$CPPFLAGS "'$(DEFS)'
test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}'
AS_IF([test -n "${cflags+set}"], [
diff --git a/template/ruby.pc.in b/template/ruby.pc.in
index d874f92c3b20..7ce4461c05df 100644
--- a/template/ruby.pc.in
+++ b/template/ruby.pc.in
@@ -39,6 +39,7 @@ sitehdrdir=@sitehdrdir@
rubyarchhdrdir=@rubyarchhdrdir@
vendorarchhdrdir=@vendorarchhdrdir@
sitearchhdrdir=@sitearchhdrdir@
+MAINLIBS=@MAINLIBS@
SOEXT=@SOEXT@
LIBPATH=@LIBPATH@
LIBRUBY_A=@LIBRUBY_A@
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index 8673c121641e..f8316cccb68e 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -279,6 +279,7 @@ MJIT_DEBUGFLAGS = $(DEBUGFLAGS)
CPPFLAGS = $(DEFS) $(ARCHDEFS) $(CPPFLAGS)
DLDFLAGS = $(LDFLAGS) -dll
+MAINLIBS = $(LIBS)
SOLIBS =
RCFILES = $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc
!ifndef RCFLAGS
@@ -821,7 +822,8 @@ s,@CPPFLAGS@,$(CPPFLAGS),;t t
s,@CXXFLAGS@,$(CXXFLAGS),;t t
s,@FFLAGS@,$(FFLAGS),;t t
s,@LDFLAGS@,$(LDFLAGS),;t t
-s,@LIBS@,$(LIBS),;t t
+s,@LIBS@,,;t t
+s,@MAINLIBS@,$(MAINLIBS),;t t
s,@exec_prefix@,$${prefix},;t t
s,@prefix@,$(prefix),;t t
s,@program_transform_name@,s,.*,$(PROGRAM_PREFIX)&$(PROGRAM_SUFFIX),,;t t
@@ -909,7 +911,7 @@ s,@LIBRUBY_SO@,$$(RUBY_SO_NAME).dll,;t t
s,@LIBRUBY_ALIASES@,$(LIBRUBY_ALIASES),;t t
s,@LIBRUBY@,$$(RUBY_SO_NAME).lib,;t t
s,@LIBRUBYARG@,$$(LIBRUBYARG_SHARED),;t t
-s,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A),;t t
+s,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A) $$(MAINLIBS),;t t
s,@LIBRUBYARG_SHARED@,$$(LIBRUBY),;t t
s,@SOLIBS@,$(SOLIBS),;t t
s,@DLDLIBS@,$(DLDLIBS),;t t

View File

@ -0,0 +1,77 @@
From eca084e4079c77c061045df9c21b219175b05228 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Mon, 6 Jan 2020 13:56:04 +0100
Subject: [PATCH] Initialize ABRT hook.
The ABRT hook used to be initialized by preludes via patches [[1], [2]].
Unfortunately, due to [[3]] and especially since [[4]], this would
require boostrapping [[5]].
To keep the things simple for now, load the ABRT hook via C.
[1]: https://bugs.ruby-lang.org/issues/8566
[2]: https://bugs.ruby-lang.org/issues/15306
[3]: https://bugs.ruby-lang.org/issues/16254
[4]: https://github.com/ruby/ruby/pull/2735
[5]: https://lists.fedoraproject.org/archives/list/ruby-sig@lists.fedoraproject.org/message/LH6L6YJOYQT4Y5ZNOO4SLIPTUWZ5V45Q/
---
abrt.c | 12 ++++++++++++
common.mk | 3 ++-
ruby.c | 4 ++++
3 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 abrt.c
diff --git a/abrt.c b/abrt.c
new file mode 100644
index 0000000000..74b0bd5c0f
--- /dev/null
+++ b/abrt.c
@@ -0,0 +1,12 @@
+#include "internal.h"
+
+void
+Init_abrt(void)
+{
+ rb_eval_string(
+ " begin\n"
+ " require 'abrt'\n"
+ " rescue LoadError\n"
+ " end\n"
+ );
+}
diff --git a/common.mk b/common.mk
index b2e5b2b6d0..f39f81da5c 100644
--- a/common.mk
+++ b/common.mk
@@ -81,7 +81,8 @@ ENC_MK = enc.mk
MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \
RUBY="$(MINIRUBY)" MINIRUBY="$(MINIRUBY)" $(mflags)
-COMMONOBJS = array.$(OBJEXT) \
+COMMONOBJS = abrt.$(OBJEXT) \
+ array.$(OBJEXT) \
ast.$(OBJEXT) \
bignum.$(OBJEXT) \
class.$(OBJEXT) \
diff --git a/ruby.c b/ruby.c
index 60c57d6259..1eec16f2c8 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1489,10 +1489,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
void Init_builtin_features(void);
+/* abrt.c */
+void Init_abrt(void);
+
static void
ruby_init_prelude(void)
{
Init_builtin_features();
+ Init_abrt();
rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"));
}
--
2.24.1

View File

@ -0,0 +1,34 @@
From 9b42fce32bff25e0569581f76f532b9d57865aef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Mon, 27 Jul 2020 14:56:05 +0200
Subject: [PATCH] Timeout the test_bug_reporter_add witout raising error.
While timeouting the threads might be still good idea, it does not seems
the timeout impacts the TestBugReporter#test_bug_reporter_add result,
because the output of the child process has been already collected
earlier.
It seems that when the system is under heavy load, the thread might not
be sheduled to finish its processing. Even finishing the child process
might take tens of seconds and therefore the test case finish might take
a while.
---
test/-ext-/bug_reporter/test_bug_reporter.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index 628fcd0340..2c677cc8a7 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -21,7 +21,7 @@ def test_bug_reporter_add
args = ["--disable-gems", "-r-test-/bug_reporter",
"-C", tmpdir]
stdin = "register_sample_bug_reporter(12345); Process.kill :SEGV, $$"
- assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT")
+ assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT", timeout_error: nil)
ensure
FileUtils.rm_rf(tmpdir) if tmpdir
end
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,358 @@
From f2cf3afc6fa1e13e960f732c0bc658ad408ee219 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 12 Jun 2020 14:12:59 +0900
Subject: [PATCH 1/3] pkey: fix potential memory leak in PKey#sign
Fix potential leak of EVP_MD_CTX object in an error path. This path is
normally unreachable, since the size of a signature generated by any
supported algorithms would not be larger than LONG_MAX.
---
ext/openssl/ossl_pkey.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index df8b425a0f..7488190e0e 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -777,8 +777,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSign");
}
- if (siglen > LONG_MAX)
+ if (siglen > LONG_MAX) {
+ EVP_MD_CTX_free(ctx);
rb_raise(ePKeyError, "signature would be too large");
+ }
sig = ossl_str_new(NULL, (long)siglen, &state);
if (state) {
EVP_MD_CTX_free(ctx);
@@ -799,8 +801,10 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSignFinal");
}
- if (siglen > LONG_MAX)
+ if (siglen > LONG_MAX) {
+ EVP_MD_CTX_free(ctx);
rb_raise(ePKeyError, "signature would be too large");
+ }
sig = ossl_str_new(NULL, (long)siglen, &state);
if (state) {
EVP_MD_CTX_free(ctx);
--
2.32.0
From 8b30ce20eb9e03180c28288e29a96308e594f860 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 2 Apr 2021 23:58:48 +0900
Subject: [PATCH 2/3] pkey: prepare pkey_ctx_apply_options() for usage by other
operations
The routine to apply Hash to EVP_PKEY_CTX_ctrl_str() is currently used
by key generation, but it is useful for other operations too. Let's
change it to a slightly more generic name.
---
ext/openssl/ossl_pkey.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 7488190e0e..fed4a2b81f 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -198,7 +198,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
}
static VALUE
-pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v))
+pkey_ctx_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v))
{
VALUE key = rb_ary_entry(i, 0), value = rb_ary_entry(i, 1);
EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)ctx_v;
@@ -214,15 +214,25 @@ pkey_gen_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v))
}
static VALUE
-pkey_gen_apply_options0(VALUE args_v)
+pkey_ctx_apply_options0(VALUE args_v)
{
VALUE *args = (VALUE *)args_v;
rb_block_call(args[1], rb_intern("each"), 0, NULL,
- pkey_gen_apply_options_i, args[0]);
+ pkey_ctx_apply_options_i, args[0]);
return Qnil;
}
+static void
+pkey_ctx_apply_options(EVP_PKEY_CTX *ctx, VALUE options, int *state)
+{
+ VALUE args[2];
+ args[0] = (VALUE)ctx;
+ args[1] = options;
+
+ rb_protect(pkey_ctx_apply_options0, (VALUE)args, state);
+}
+
struct pkey_blocking_generate_arg {
EVP_PKEY_CTX *ctx;
EVP_PKEY *pkey;
@@ -330,11 +340,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam)
}
if (!NIL_P(options)) {
- VALUE args[2];
-
- args[0] = (VALUE)ctx;
- args[1] = options;
- rb_protect(pkey_gen_apply_options0, (VALUE)args, &state);
+ pkey_ctx_apply_options(ctx, options, &state);
if (state) {
EVP_PKEY_CTX_free(ctx);
rb_jump_tag(state);
--
2.32.0
From 4c7b0f91da666961d11908b94520db4e09ce4e67 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 18 Jul 2020 20:40:39 +0900
Subject: [PATCH 3/3] pkey: allow setting algorithm-specific options in #sign
and #verify
Similarly to OpenSSL::PKey.generate_key and .generate_parameters, let
OpenSSL::PKey::PKey#sign and #verify take an optional parameter for
specifying control strings for EVP_PKEY_CTX_ctrl_str().
---
ext/openssl/ossl_pkey.c | 113 ++++++++++++++++++++++------------
test/openssl/test_pkey_rsa.rb | 34 +++++-----
2 files changed, 89 insertions(+), 58 deletions(-)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index fed4a2b81f..22e9f19982 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -739,33 +739,51 @@ ossl_pkey_public_to_pem(VALUE self)
}
/*
- * call-seq:
- * pkey.sign(digest, data) -> String
+ * call-seq:
+ * pkey.sign(digest, data [, options]) -> string
*
- * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must
- * be provided. The return value is again a String containing the signature.
- * A PKeyError is raised should errors occur.
- * Any previous state of the Digest instance is irrelevant to the signature
- * outcome, the digest instance is reset to its initial state during the
- * operation.
+ * Hashes and signs the +data+ using a message digest algorithm +digest+ and
+ * a private key +pkey+.
*
- * == Example
- * data = 'Sign me!'
- * digest = OpenSSL::Digest.new('SHA256')
- * pkey = OpenSSL::PKey::RSA.new(2048)
- * signature = pkey.sign(digest, data)
+ * See #verify for the verification operation.
+ *
+ * See also the man page EVP_DigestSign(3).
+ *
+ * +digest+::
+ * A String that represents the message digest algorithm name, or +nil+
+ * if the PKey type requires no digest algorithm.
+ * For backwards compatibility, this can be an instance of OpenSSL::Digest.
+ * Its state will not affect the signature.
+ * +data+::
+ * A String. The data to be hashed and signed.
+ * +options+::
+ * A Hash that contains algorithm specific control operations to \OpenSSL.
+ * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details.
+ * +options+ parameter was added in version 2.3.
+ *
+ * Example:
+ * data = "Sign me!"
+ * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048)
+ * signopts = { rsa_padding_mode: "pss" }
+ * signature = pkey.sign("SHA256", data, signopts)
+ *
+ * # Creates a copy of the RSA key pkey, but without the private components
+ * pub_key = pkey.public_key
+ * puts pub_key.verify("SHA256", signature, data, signopts) # => true
*/
static VALUE
-ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
+ossl_pkey_sign(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
+ VALUE digest, data, options, sig;
const EVP_MD *md = NULL;
EVP_MD_CTX *ctx;
+ EVP_PKEY_CTX *pctx;
size_t siglen;
int state;
- VALUE sig;
pkey = GetPrivPKeyPtr(self);
+ rb_scan_args(argc, argv, "21", &digest, &data, &options);
if (!NIL_P(digest))
md = ossl_evp_get_digestbyname(digest);
StringValue(data);
@@ -773,10 +791,17 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
- if (EVP_DigestSignInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) {
+ if (EVP_DigestSignInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestSignInit");
}
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(pctx, options, &state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data),
RSTRING_LEN(data)) < 1) {
@@ -828,35 +853,40 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
}
/*
- * call-seq:
- * pkey.verify(digest, signature, data) -> String
+ * call-seq:
+ * pkey.verify(digest, signature, data [, options]) -> true or false
*
- * To verify the String _signature_, _digest_, an instance of
- * OpenSSL::Digest, must be provided to re-compute the message digest of the
- * original _data_, also a String. The return value is +true+ if the
- * signature is valid, +false+ otherwise. A PKeyError is raised should errors
- * occur.
- * Any previous state of the Digest instance is irrelevant to the validation
- * outcome, the digest instance is reset to its initial state during the
- * operation.
+ * Verifies the +signature+ for the +data+ using a message digest algorithm
+ * +digest+ and a public key +pkey+.
*
- * == Example
- * data = 'Sign me!'
- * digest = OpenSSL::Digest.new('SHA256')
- * pkey = OpenSSL::PKey::RSA.new(2048)
- * signature = pkey.sign(digest, data)
- * pub_key = pkey.public_key
- * puts pub_key.verify(digest, signature, data) # => true
+ * Returns +true+ if the signature is successfully verified, +false+ otherwise.
+ * The caller must check the return value.
+ *
+ * See #sign for the signing operation and an example.
+ *
+ * See also the man page EVP_DigestVerify(3).
+ *
+ * +digest+::
+ * See #sign.
+ * +signature+::
+ * A String containing the signature to be verified.
+ * +data+::
+ * See #sign.
+ * +options+::
+ * See #sign. +options+ parameter was added in version 2.3.
*/
static VALUE
-ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
+ossl_pkey_verify(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
+ VALUE digest, sig, data, options;
const EVP_MD *md = NULL;
EVP_MD_CTX *ctx;
- int ret;
+ EVP_PKEY_CTX *pctx;
+ int state, ret;
GetPKey(self, pkey);
+ rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options);
ossl_pkey_check_public_key(pkey);
if (!NIL_P(digest))
md = ossl_evp_get_digestbyname(digest);
@@ -866,10 +896,17 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
ctx = EVP_MD_CTX_new();
if (!ctx)
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
- if (EVP_DigestVerifyInit(ctx, NULL, md, /* engine */NULL, pkey) < 1) {
+ if (EVP_DigestVerifyInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) {
EVP_MD_CTX_free(ctx);
ossl_raise(ePKeyError, "EVP_DigestVerifyInit");
}
+ if (!NIL_P(options)) {
+ pkey_ctx_apply_options(pctx, options, &state);
+ if (state) {
+ EVP_MD_CTX_free(ctx);
+ rb_jump_tag(state);
+ }
+ }
#if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig),
RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data),
@@ -1042,8 +1079,8 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
- rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
- rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
+ rb_define_method(cPKey, "sign", ossl_pkey_sign, -1);
+ rb_define_method(cPKey, "verify", ossl_pkey_verify, -1);
rb_define_method(cPKey, "derive", ossl_pkey_derive, -1);
id_private_q = rb_intern("private?");
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 88164c3b52..d1e68dbc9f 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -117,27 +117,21 @@ def test_sign_verify
assert_equal false, rsa1024.verify("SHA256", signature1, data)
end
- def test_digest_state_irrelevant_sign
+ def test_sign_verify_options
key = Fixtures.pkey("rsa1024")
- digest1 = OpenSSL::Digest.new('SHA1')
- digest2 = OpenSSL::Digest.new('SHA1')
- data = 'Sign me!'
- digest1 << 'Change state of digest1'
- sig1 = key.sign(digest1, data)
- sig2 = key.sign(digest2, data)
- assert_equal(sig1, sig2)
- end
-
- def test_digest_state_irrelevant_verify
- key = Fixtures.pkey("rsa1024")
- digest1 = OpenSSL::Digest.new('SHA1')
- digest2 = OpenSSL::Digest.new('SHA1')
- data = 'Sign me!'
- sig = key.sign(digest1, data)
- digest1.reset
- digest1 << 'Change state of digest1'
- assert(key.verify(digest1, sig, data))
- assert(key.verify(digest2, sig, data))
+ data = "Sign me!"
+ pssopts = {
+ "rsa_padding_mode" => "pss",
+ "rsa_pss_saltlen" => 20,
+ "rsa_mgf1_md" => "SHA1"
+ }
+ sig_pss = key.sign("SHA256", data, pssopts)
+ assert_equal 128, sig_pss.bytesize
+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts)
+ assert_equal true, key.verify_pss("SHA256", sig_pss, data,
+ salt_length: 20, mgf1_hash: "SHA1")
+ # Defaults to PKCS #1 v1.5 padding => verification failure
+ assert_equal false, key.verify("SHA256", sig_pss, data)
end
def test_verify_empty_rsa
--
2.32.0

View File

@ -0,0 +1,186 @@
From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
Date: Thu, 5 Aug 2021 20:09:25 +0900
Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062]
---
vm_eval.c | 4 +++-
vm_insnhelper.c | 7 +++++--
vm_method.c | 41 ++++++++++++++++++++++++++---------------
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/vm_eval.c b/vm_eval.c
index 6d4b5c3c0b28..7ce9f157e671 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
{
struct rb_class_cc_entries *ccs;
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
+ VALUE ccs_data;
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) {
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
// ok
+ ccs = (struct rb_class_cc_entries *)ccs_data;
}
else {
ccs = vm_ccs_create(klass, cme);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 14928b2afe8e..e186376b24d7 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1637,9 +1637,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
const ID mid = vm_ci_mid(ci);
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs = NULL;
+ VALUE ccs_data;
if (cc_tbl) {
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
+ ccs = (struct rb_class_cc_entries *)ccs_data;
const int ccs_len = ccs->len;
VM_ASSERT(vm_ccs_verify(ccs, mid, klass));
@@ -1706,8 +1708,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
if (ccs == NULL) {
VM_ASSERT(cc_tbl != NULL);
- if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) {
+ if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) {
// rb_callable_method_entry() prepares ccs.
+ ccs = (struct rb_class_cc_entries *)ccs_data;
}
else {
// TODO: required?
diff --git a/vm_method.c b/vm_method.c
index 016dba1dbb18..1fd0bd57f7ca 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid)
{
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
if (cc_tbl) {
- const struct rb_class_cc_entries *ccs;
+ VALUE ccs;
if (target_mid) {
- if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) {
+ if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) {
fprintf(stderr, " [CCTB] %p\n", (void *)cc_tbl);
- vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL);
+ vm_ccs_dump_i(target_mid, ccs, NULL);
}
}
else {
@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
fprintf(stderr, "# vm_mtbl\n");
while (klass) {
rp_m(" -> ", klass);
- rb_method_entry_t *me;
+ VALUE me;
if (RCLASS_M_TBL(klass)) {
if (target_mid != 0) {
- if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) {
+ if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) {
rp_m(" [MTBL] ", me);
}
}
@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
}
if (RCLASS_CALLABLE_M_TBL(klass)) {
if (target_mid != 0) {
- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) {
+ if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) {
rp_m(" [CM**] ", me);
}
}
@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
// check only current class
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
- struct rb_class_cc_entries *ccs;
+ VALUE ccs_data;
// invalidate CCs
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
rb_vm_ccs_free(ccs);
rb_id_table_delete(cc_tbl, mid);
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
}
else {
rb_vm_t *vm = GET_VM();
- if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
+ VALUE cme_data = (VALUE) cme;
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
rb_id_table_delete(vm->negative_cme_table, mid);
- vm_me_invalidate_cache((rb_callable_method_entry_t *)cme);
+ vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data);
RB_DEBUG_COUNTER_INC(cc_invalidate_negative);
}
@@ -1023,6 +1025,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
{
struct rb_id_table *mtbl;
const rb_callable_method_entry_t *cme;
+ VALUE cme_data;
if (me) {
if (me->defined_class == 0) {
@@ -1032,7 +1035,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
- if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) {
+ if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
+ cme = (rb_callable_method_entry_t *)cme_data;
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
VM_ASSERT(callable_method_entry_p(cme));
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
@@ -1076,9 +1080,10 @@ cached_callable_method_entry(VALUE klass, ID mid)
ASSERT_vm_locking();
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
- struct rb_class_cc_entries *ccs;
+ VALUE ccs_data;
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
VM_ASSERT(vm_ccs_p(ccs));
if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) {
@@ -1104,12 +1109,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs;
+ VALUE ccs_data;
if (!cc_tbl) {
cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
}
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
+ ccs = (struct rb_class_cc_entries *)ccs_data;
VM_ASSERT(ccs->cme == cme);
}
else {
@@ -1123,8 +1130,12 @@ negative_cme(ID mid)
{
rb_vm_t *vm = GET_VM();
const rb_callable_method_entry_t *cme;
+ VALUE cme_data;
- if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
+ cme = (rb_callable_method_entry_t *)cme_data;
+ }
+ else {
cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL);
rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme);
}

View File

@ -0,0 +1,58 @@
From 72317b333b85eed483ad00bcd4f40944019a7c13 Mon Sep 17 00:00:00 2001
From: "xtkoba+ruby@gmail.com" <xtkoba+ruby@gmail.com>
Date: Fri, 13 Aug 2021 13:45:53 +0000
Subject: [PATCH] Ignore `DW_FORM_ref_addr` [Bug #17052]
Ignore `DW_FORM_ref_addr` form and other forms that are not supposed
to be used currently.
---
addr2line.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/addr2line.c b/addr2line.c
index fed1a8da84e5..92c6da5e3bea 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -1593,14 +1593,31 @@ di_read_cu(DebugInfoReader *reader)
}
static void
-read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line)
+read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line)
{
char *p = reader->p;
char *q = reader->q;
int level = reader->level;
DIE die;
- reader->p = reader->current_cu + abstract_origin;
+ switch (form) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ reader->p = reader->current_cu + abstract_origin;
+ break;
+ case DW_FORM_ref_addr:
+ goto finish; /* not supported yet */
+ case DW_FORM_ref_sig8:
+ goto finish; /* not supported yet */
+ case DW_FORM_ref_sup4:
+ case DW_FORM_ref_sup8:
+ goto finish; /* not supported yet */
+ default:
+ goto finish;
+ }
if (!di_read_die(reader, &die)) goto finish;
/* enumerate abbrev */
@@ -1665,7 +1682,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
/* 1 or 3 */
break; /* goto skip_die; */
case DW_AT_abstract_origin:
- read_abstract_origin(reader, v.as.uint64, &line);
+ read_abstract_origin(reader, v.form, v.as.uint64, &line);
break; /* goto skip_die; */
}
}

View File

@ -0,0 +1,142 @@
From 8f948ed68a4ed6c05ff66d822711e3b70ae4bb3f Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 27 Sep 2021 13:32:03 +0900
Subject: [PATCH 1/3] ext/openssl/ossl.h: add helper macros for
OpenSSL/LibreSSL versions
Add following convenient macros:
- OSSL_IS_LIBRESSL
- OSSL_OPENSSL_PREREQ(maj, min, pat)
- OSSL_LIBRESSL_PREREQ(maj, min, pat)
---
ext/openssl/ossl.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index c20f506bda..a0cef29d74 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -43,6 +43,18 @@
#include <openssl/evp.h>
#include <openssl/dh.h>
+#ifndef LIBRESSL_VERSION_NUMBER
+# define OSSL_IS_LIBRESSL 0
+# define OSSL_OPENSSL_PREREQ(maj, min, pat) \
+ (OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12))
+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0
+#else
+# define OSSL_IS_LIBRESSL 1
+# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0
+# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \
+ (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12))
+#endif
+
/*
* Common Module
*/
--
2.32.0
From bbf235091e49807ece8f3a3df95bbfcc9d3ab43d Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 05:37:01 +0900
Subject: [PATCH 2/3] ts: use TS_VERIFY_CTX_set_certs instead of
TS_VERIFY_CTS_set_certs
OpenSSL 3.0 fixed the typo in the function name and replaced the
current 'CTS' version with a macro.
---
ext/openssl/extconf.rb | 5 ++++-
ext/openssl/openssl_missing.h | 5 +++++
ext/openssl/ossl_ts.c | 2 +-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 17d93443fc..09cae05b72 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -166,7 +166,7 @@ def find_openssl_library
have_func("TS_STATUS_INFO_get0_status")
have_func("TS_STATUS_INFO_get0_text")
have_func("TS_STATUS_INFO_get0_failure_info")
-have_func("TS_VERIFY_CTS_set_certs")
+have_func("TS_VERIFY_CTS_set_certs(NULL, NULL)", "openssl/ts.h")
have_func("TS_VERIFY_CTX_set_store")
have_func("TS_VERIFY_CTX_add_flags")
have_func("TS_RESP_CTX_set_time_cb")
@@ -175,6 +175,9 @@ def find_openssl_library
# added in 1.1.1
have_func("EVP_PKEY_check")
+
+# added in 3.0.0
+have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index e575415f49..fe486bcfcf 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -242,4 +242,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
} while (0)
#endif
+/* added in 3.0.0 */
+#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS)
+# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
+#endif
+
#endif /* _OSSL_OPENSSL_MISSING_H_ */
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c
index 692c0d620f..f1da7c1947 100644
--- a/ext/openssl/ossl_ts.c
+++ b/ext/openssl/ossl_ts.c
@@ -820,7 +820,7 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
X509_up_ref(cert);
}
- TS_VERIFY_CTS_set_certs(ctx, x509inter);
+ TS_VERIFY_CTX_set_certs(ctx, x509inter);
TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
TS_VERIFY_CTX_set_store(ctx, x509st);
--
2.32.0
From 5fba3bc1df93ab6abc3ea53be3393480f36ea259 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 19 Mar 2021 19:18:25 +0900
Subject: [PATCH 3/3] ssl: use SSL_get_rbio() to check if SSL is started or not
Use SSL_get_rbio() instead of SSL_get_fd(). SSL_get_fd() internally
calls SSL_get_rbio() and it's enough for our purpose.
In OpenSSL 3.0, SSL_get_fd() leaves an entry in the OpenSSL error queue
if BIO has not been set up yet, and we would have to clean it up.
---
ext/openssl/ossl_ssl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 4b7efa39f5..ec430bfb0c 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1535,8 +1535,8 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
static inline int
ssl_started(SSL *ssl)
{
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
- return SSL_get_fd(ssl) >= 0;
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
+ return SSL_get_rbio(ssl) != NULL;
}
static void
--
2.32.0

View File

@ -0,0 +1,93 @@
From 96684439e96aa92e10376b5be45f006772028295 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Thu, 21 Oct 2021 13:02:38 +0200
Subject: [PATCH] Properly exclude test cases.
Lets consider the following scenario:
~~~
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):001:0> p suite
OpenSSL::TestEC
=> OpenSSL::TestEC
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):002:0> p all_test_methods
["test_ECPrivateKey", "test_ECPrivateKey_encrypted", "test_PUBKEY", "test_check_key", "test_derive_key", "test_dh_compute_key", "test_dsa_sign_asn1_FIPS186_3", "test_ec_group", "test_ec_key", "test_ec_point", "test_ec_point_add", "test_ec_point_mul", "test_generate", "test_marshal", "test_sign_verify", "test_sign_verify_raw"]
=>
["test_ECPrivateKey",
"test_ECPrivateKey_encrypted",
"test_PUBKEY",
"test_check_key",
"test_derive_key",
"test_dh_compute_key",
"test_dsa_sign_asn1_FIPS186_3",
"test_ec_group",
"test_ec_key",
"test_ec_point",
"test_ec_point_add",
"test_ec_point_mul",
"test_generate",
"test_marshal",
"test_sign_verify",
"test_sign_verify_raw"]
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):003:0> p filter
/\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/
=> /\A(?=.*)(?!.*(?-mix:(?-mix:memory_leak)|(?-mix:OpenSSL::TestEC.test_check_key)))/
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):004:0> method = "test_check_key"
=> "test_check_key"
~~~
The intention here is to exclude the `test_check_key` test case.
Unfortunately this does not work as expected, because the negative filter
is never checked:
~~~
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):005:0> filter === method
=> true
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):006:0> filter === "#{suite}##{method}"
=> false
irb(#<Test::Unit::AutoRunner::Runner:0x0000560f68afc3c8>):007:0> filter === method || filter === "#{suite}##{method}"
=> true
~~~
Therefore always filter against the fully qualified method name
`#{suite}##{method}`, which should provide the expected result.
However, if plain string filter is used, keep checking also only the
method name.
This resolves [Bug #16936].
---
tool/lib/minitest/unit.rb | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/tool/lib/minitest/unit.rb b/tool/lib/minitest/unit.rb
index c58a609bfa..d5af6cb906 100644
--- a/tool/lib/minitest/unit.rb
+++ b/tool/lib/minitest/unit.rb
@@ -956,9 +956,15 @@ def _run_suite suite, type
all_test_methods = suite.send "#{type}_methods"
- filtered_test_methods = all_test_methods.find_all { |m|
- filter === m || filter === "#{suite}##{m}"
- }
+ filtered_test_methods = if Regexp === filter
+ all_test_methods.find_all { |m|
+ filter === "#{suite}##{m}"
+ }
+ else
+ all_test_methods.find_all {|m|
+ filter === m || filter === "#{suite}##{m}"
+ }
+ end
leakchecker = LeakChecker.new
--
2.32.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 3b425ca..40e748c 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1870,6 +1870,11 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
return str;
GetSSL(self, ssl);
+
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
+ SSL_set_options(ssl, SSL_OP_IGNORE_UNEXPECTED_EOF);
+#endif
+
io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
if (ssl_started(ssl)) {

View File

@ -0,0 +1,229 @@
From 3b91792d3d644d6d6b0059cb315c9fe5d3626bab Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@ruby-lang.org>
Date: Sat, 6 Mar 2021 00:03:57 +0900
Subject: [PATCH] Support GCC's DWARF 5 [Bug #17585]
Co-Authored-By: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com>
---
addr2line.c | 119 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 97 insertions(+), 22 deletions(-)
diff --git a/addr2line.c b/addr2line.c
index 0029cffbca..855efb40d4 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -159,11 +159,12 @@ typedef struct obj_info {
struct dwarf_section debug_info;
struct dwarf_section debug_line;
struct dwarf_section debug_ranges;
+ struct dwarf_section debug_rnglists;
struct dwarf_section debug_str;
struct obj_info *next;
} obj_info_t;
-#define DWARF_SECTION_COUNT 5
+#define DWARF_SECTION_COUNT 6
static struct dwarf_section *
obj_dwarf_section_at(obj_info_t *obj, int n)
@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
&obj->debug_info,
&obj->debug_line,
&obj->debug_ranges,
+ &obj->debug_rnglists,
&obj->debug_str
};
if (n < 0 || DWARF_SECTION_COUNT <= n) {
@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
FILL_LINE();
break;
case DW_LNS_advance_pc:
- a = uleb128((char **)&p);
+ a = uleb128((char **)&p) * header.minimum_instruction_length;
addr += a;
break;
case DW_LNS_advance_line: {
@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
/* isa = (unsigned int)*/(void)uleb128((char **)&p);
break;
case 0:
- a = *(unsigned char *)p++;
+ a = uleb128((char **)&p);
op = *p++;
switch (op) {
case DW_LNE_end_sequence:
@@ -808,6 +810,18 @@ enum
DW_FORM_addrx4 = 0x2c
};
+/* Range list entry encodings */
+enum {
+ DW_RLE_end_of_list = 0x00,
+ DW_RLE_base_addressx = 0x01,
+ DW_RLE_startx_endx = 0x02,
+ DW_RLE_startx_length = 0x03,
+ DW_RLE_offset_pair = 0x04,
+ DW_RLE_base_address = 0x05,
+ DW_RLE_start_end = 0x06,
+ DW_RLE_start_length = 0x07
+};
+
enum {
VAL_none = 0,
VAL_cstr = 1,
@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
reader->current_low_pc = 0;
}
+static void
+di_skip_die_attributes(char **p)
+{
+ for (;;) {
+ uint64_t at = uleb128(p);
+ uint64_t form = uleb128(p);
+ if (!at && !form) break;
+ switch (form) {
+ default:
+ break;
+ case DW_FORM_implicit_const:
+ sleb128(p);
+ break;
+ }
+ }
+}
+
static void
di_read_debug_abbrev_cu(DebugInfoReader *reader)
{
@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
prev = abbrev_number;
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
}
}
@@ -1244,12 +1270,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
/* skip 255th record */
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
if (n == 0) {
fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
@@ -1257,12 +1278,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
}
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
}
return p;
}
@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v)
}
}
+static uint64_t
+read_dw_form_addr(DebugInfoReader *reader, char **ptr)
+{
+ char *p = *ptr;
+ *ptr = p + reader->format;
+ if (reader->format == 4) {
+ return read_uint32(&p);
+ } else if (reader->format == 8) {
+ return read_uint64(&p);
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+}
+
static uintptr_t
ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
{
@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
}
else if (ptr->ranges_set) {
/* TODO: support base address selection entry */
- char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
+ char *p;
uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
+ if (reader->obj->debug_rnglists.ptr) {
+ p = reader->obj->debug_rnglists.ptr + ptr->ranges;
+ for (;;) {
+ uint8_t rle = read_uint8(&p);
+ uintptr_t base_address = 0;
+ uintptr_t from, to;
+ if (rle == DW_RLE_end_of_list) break;
+ switch (rle) {
+ case DW_RLE_base_addressx:
+ uleb128(&p);
+ break;
+ case DW_RLE_startx_endx:
+ uleb128(&p);
+ uleb128(&p);
+ break;
+ case DW_RLE_startx_length:
+ uleb128(&p);
+ uleb128(&p);
+ break;
+ case DW_RLE_offset_pair:
+ from = base_address + uleb128(&p);
+ to = base_address + uleb128(&p);
+ if (base + from <= addr && addr < base + to) {
+ return from;
+ }
+ break;
+ case DW_RLE_base_address:
+ base_address = read_dw_form_addr(reader, &p);
+ break;
+ case DW_RLE_start_end:
+ read_dw_form_addr(reader, &p);
+ read_dw_form_addr(reader, &p);
+ break;
+ case DW_RLE_start_length:
+ read_dw_form_addr(reader, &p);
+ uleb128(&p);
+ break;
+ }
+ }
+ return false;
+ }
+ p = reader->obj->debug_ranges.ptr + ptr->ranges;
for (;;) {
uintptr_t from = read_uintptr(&p);
uintptr_t to = read_uintptr(&p);
@@ -1750,6 +1823,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
".debug_info",
".debug_line",
".debug_ranges",
+ ".debug_rnglists",
".debug_str"
};
@@ -2006,6 +2080,7 @@ found_mach_header:
"__debug_info",
"__debug_line",
"__debug_ranges",
+ "__debug_rnglists",
"__debug_str"
};
struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,831 @@
From cf070378020088cd7e69b1cb08be68152ab8a078 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sun, 17 May 2020 18:25:38 +0900
Subject: [PATCH 1/3] pkey: implement #to_text using EVP API
Use EVP_PKEY_print_private() instead of the low-level API *_print()
functions, such as RSA_print().
EVP_PKEY_print_*() family was added in OpenSSL 1.0.0.
Note that it falls back to EVP_PKEY_print_public() and
EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH
type for which _private() fails if the private component is not set in
the pkey object.
Since the new API works in the same way for all key types, we now
implement #to_text in the base class OpenSSL::PKey::PKey rather than in
each subclass.
---
ext/openssl/ossl_pkey.c | 38 +++++++++++++++++++++++++++++++++++++
ext/openssl/ossl_pkey_dh.c | 29 ----------------------------
ext/openssl/ossl_pkey_dsa.c | 29 ----------------------------
ext/openssl/ossl_pkey_ec.c | 27 --------------------------
ext/openssl/ossl_pkey_rsa.c | 31 ------------------------------
test/openssl/test_pkey.rb | 5 +++++
6 files changed, 43 insertions(+), 116 deletions(-)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index f9282b9417..21cd4b2cda 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -539,6 +539,43 @@ ossl_pkey_inspect(VALUE self)
OBJ_nid2sn(nid));
}
+/*
+ * call-seq:
+ * pkey.to_text -> string
+ *
+ * Dumps key parameters, public key, and private key components contained in
+ * the key into a human-readable text.
+ *
+ * This is intended for debugging purpose.
+ *
+ * See also the man page EVP_PKEY_print_private(3).
+ */
+static VALUE
+ossl_pkey_to_text(VALUE self)
+{
+ EVP_PKEY *pkey;
+ BIO *bio;
+
+ GetPKey(self, pkey);
+ if (!(bio = BIO_new(BIO_s_mem())))
+ ossl_raise(ePKeyError, "BIO_new");
+
+ if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1)
+ goto out;
+
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "EVP_PKEY_print_params");
+
+ out:
+ return ossl_membio2str(bio);
+}
+
VALUE
ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der)
{
@@ -1039,6 +1076,7 @@ Init_ossl_pkey(void)
rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
+ rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0);
rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1);
rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 6b477b077c..acd3bf474e 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -266,34 +266,6 @@ ossl_dh_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dh.to_text -> aString
- *
- * Prints all parameters of key to buffer
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
- * Don't use :-)) (I's up to you)
- */
-static VALUE
-ossl_dh_to_text(VALUE self)
-{
- DH *dh;
- BIO *out;
- VALUE str;
-
- GetDH(self, dh);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eDHError, NULL);
- }
- if (!DHparams_print(out, dh)) {
- BIO_free(out);
- ossl_raise(eDHError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* dh.public_key -> aDH
@@ -426,7 +398,6 @@ Init_ossl_dh(void)
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
rb_define_method(cDH, "export", ossl_dh_export, 0);
rb_define_alias(cDH, "to_pem", "export");
rb_define_alias(cDH, "to_s", "export");
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index 1c5a8a737e..f017cceb4a 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -264,34 +264,6 @@ ossl_dsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dsa.to_text -> aString
- *
- * Prints all parameters of key to buffer
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
- * Don't use :-)) (I's up to you)
- */
-static VALUE
-ossl_dsa_to_text(VALUE self)
-{
- DSA *dsa;
- BIO *out;
- VALUE str;
-
- GetDSA(self, dsa);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eDSAError, NULL);
- }
- if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
- BIO_free(out);
- ossl_raise(eDSAError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* dsa.public_key -> aDSA
@@ -469,7 +441,6 @@ Init_ossl_dsa(void)
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
- rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0);
rb_define_method(cDSA, "export", ossl_dsa_export, -1);
rb_define_alias(cDSA, "to_pem", "export");
rb_define_alias(cDSA, "to_s", "export");
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index c2534251c3..ecb8305184 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -417,32 +417,6 @@ ossl_ec_key_to_der(VALUE self)
else
return ossl_pkey_export_spki(self, 1);
}
-
-/*
- * call-seq:
- * key.to_text => String
- *
- * See the OpenSSL documentation for EC_KEY_print()
- */
-static VALUE ossl_ec_key_to_text(VALUE self)
-{
- EC_KEY *ec;
- BIO *out;
- VALUE str;
-
- GetEC(self, ec);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eECError, "BIO_new(BIO_s_mem())");
- }
- if (!EC_KEY_print(out, ec, 0)) {
- BIO_free(out);
- ossl_raise(eECError, "EC_KEY_print");
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* key.generate_key! => self
@@ -1633,7 +1607,6 @@ void Init_ossl_ec(void)
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
rb_define_alias(cEC, "to_pem", "export");
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
- rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 43f82cb29e..7a7e66dbda 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -587,36 +587,6 @@ ossl_rsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * rsa.to_text => String
- *
- * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
- *
- * Dumps all parameters of a keypair to a String
- *
- * Don't use :-)) (It's up to you)
- */
-static VALUE
-ossl_rsa_to_text(VALUE self)
-{
- RSA *rsa;
- BIO *out;
- VALUE str;
-
- GetRSA(self, rsa);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eRSAError, NULL);
- }
- if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
- BIO_free(out);
- ossl_raise(eRSAError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* rsa.public_key -> RSA
@@ -738,7 +708,6 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
- rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
rb_define_method(cRSA, "export", ossl_rsa_export, -1);
rb_define_alias(cRSA, "to_pem", "export");
rb_define_alias(cRSA, "to_s", "export");
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index 5307fe5b08..3630458b3c 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -151,4 +151,9 @@ def test_x25519
assert_equal bob_pem, bob.public_to_pem
assert_equal [shared_secret].pack("H*"), alice.derive(bob)
end
+
+ def test_to_text
+ rsa = Fixtures.pkey("rsa1024")
+ assert_include rsa.to_text, "publicExponent"
+ end
end
--
2.32.0
From 0c45b22e485bfa62f4d704b08e3704e6444118c4 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Thu, 15 Apr 2021 19:11:32 +0900
Subject: [PATCH 2/3] pkey: implement {DH,DSA,RSA}#public_key in Ruby
The low-level API that is used to implement #public_key is deprecated
in OpenSSL 3.0. It is actually very simple to implement in another way,
using existing methods only, in much shorter code. Let's do it.
While we are at it, the documentation is updated to recommend against
using #public_key. Now that OpenSSL::PKey::PKey implements public_to_der
method, there is no real use case for #public_key in newly written Ruby
programs.
---
ext/openssl/lib/openssl/pkey.rb | 55 ++++++++++++++++++++++++++++
ext/openssl/ossl_pkey_dh.c | 63 +++++++--------------------------
ext/openssl/ossl_pkey_dsa.c | 42 ----------------------
ext/openssl/ossl_pkey_rsa.c | 58 +-----------------------------
test/openssl/test_pkey_rsa.rb | 37 ++++++++++---------
5 files changed, 87 insertions(+), 168 deletions(-)
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index 53ee52f98b..569559e1ce 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -10,6 +10,30 @@ module OpenSSL::PKey
class DH
include OpenSSL::Marshal
+ # :call-seq:
+ # dh.public_key -> dhnew
+ #
+ # Returns a new DH instance that carries just the \DH parameters.
+ #
+ # Contrary to the method name, the returned DH object contains only
+ # parameters and not the public key.
+ #
+ # This method is provided for backwards compatibility. In most cases, there
+ # is no need to call this method.
+ #
+ # For the purpose of re-generating the key pair while keeping the
+ # parameters, check OpenSSL::PKey.generate_key.
+ #
+ # Example:
+ # # OpenSSL::PKey::DH.generate by default generates a random key pair
+ # dh1 = OpenSSL::PKey::DH.generate(2048)
+ # p dh1.priv_key #=> #<OpenSSL::BN 1288347...>
+ # dhcopy = dh1.public_key
+ # p dhcopy.priv_key #=> nil
+ def public_key
+ DH.new(to_der)
+ end
+
# :call-seq:
# dh.compute_key(pub_bn) -> string
#
@@ -89,6 +113,22 @@ def new(*args, &blk) # :nodoc:
class DSA
include OpenSSL::Marshal
+ # :call-seq:
+ # dsa.public_key -> dsanew
+ #
+ # Returns a new DSA instance that carries just the \DSA parameters and the
+ # public key.
+ #
+ # This method is provided for backwards compatibility. In most cases, there
+ # is no need to call this method.
+ #
+ # For the purpose of serializing the public key, to PEM or DER encoding of
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and
+ # PKey#public_to_der.
+ def public_key
+ OpenSSL::PKey.read(public_to_der)
+ end
+
class << self
# :call-seq:
# DSA.generate(size) -> dsa
@@ -159,6 +199,21 @@ def to_bn(conversion_form = group.point_conversion_form)
class RSA
include OpenSSL::Marshal
+ # :call-seq:
+ # rsa.public_key -> rsanew
+ #
+ # Returns a new RSA instance that carries just the public key components.
+ #
+ # This method is provided for backwards compatibility. In most cases, there
+ # is no need to call this method.
+ #
+ # For the purpose of serializing the public key, to PEM or DER encoding of
+ # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and
+ # PKey#public_to_der.
+ def public_key
+ OpenSSL::PKey.read(public_to_der)
+ end
+
class << self
# :call-seq:
# RSA.generate(size, exponent = 65537) -> RSA
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index acd3bf474e..a512b209d3 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -266,48 +266,6 @@ ossl_dh_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dh.public_key -> aDH
- *
- * Returns a new DH instance that carries just the public information, i.e.
- * the prime _p_ and the generator _g_, but no public/private key yet. Such
- * a pair may be generated using DH#generate_key!. The "public key" needed
- * for a key exchange with DH#compute_key is considered as per-session
- * information and may be retrieved with DH#pub_key once a key pair has
- * been generated.
- * If the current instance already contains private information (and thus a
- * valid public/private key pair), this information will no longer be present
- * in the new instance generated by DH#public_key. This feature is helpful for
- * publishing the Diffie-Hellman parameters without leaking any of the private
- * per-session information.
- *
- * === Example
- * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set
- * public_key = dh.public_key # contains only prime and generator
- * parameters = public_key.to_der # it's safe to publish this
- */
-static VALUE
-ossl_dh_to_public_key(VALUE self)
-{
- EVP_PKEY *pkey;
- DH *orig_dh, *dh;
- VALUE obj;
-
- obj = rb_obj_alloc(rb_obj_class(self));
- GetPKey(obj, pkey);
-
- GetDH(self, orig_dh);
- dh = DHparams_dup(orig_dh);
- if (!dh)
- ossl_raise(eDHError, "DHparams_dup");
- if (!EVP_PKEY_assign_DH(pkey, dh)) {
- DH_free(dh);
- ossl_raise(eDHError, "EVP_PKEY_assign_DH");
- }
- return obj;
-}
-
/*
* call-seq:
* dh.params_ok? -> true | false
@@ -384,14 +342,20 @@ Init_ossl_dh(void)
* The per-session private key, an OpenSSL::BN.
*
* === Example of a key exchange
- * dh1 = OpenSSL::PKey::DH.new(2048)
- * der = dh1.public_key.to_der #you may send this publicly to the participating party
- * dh2 = OpenSSL::PKey::DH.new(der)
- * dh2.generate_key! #generate the per-session key pair
- * symm_key1 = dh1.compute_key(dh2.pub_key)
- * symm_key2 = dh2.compute_key(dh1.pub_key)
+ * # you may send the parameters (der) and own public key (pub1) publicly
+ * # to the participating party
+ * dh1 = OpenSSL::PKey::DH.new(2048)
+ * der = dh1.to_der
+ * pub1 = dh1.pub_key
+ *
+ * # the other party generates its per-session key pair
+ * dhparams = OpenSSL::PKey::DH.new(der)
+ * dh2 = OpenSSL::PKey.generate_key(dhparams)
+ * pub2 = dh2.pub_key
*
- * puts symm_key1 == symm_key2 # => true
+ * symm_key1 = dh1.compute_key(pub2)
+ * symm_key2 = dh2.compute_key(pub1)
+ * puts symm_key1 == symm_key2 # => true
*/
cDH = rb_define_class_under(mPKey, "DH", cPKey);
rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
@@ -402,7 +366,6 @@ Init_ossl_dh(void)
rb_define_alias(cDH, "to_pem", "export");
rb_define_alias(cDH, "to_s", "export");
rb_define_method(cDH, "to_der", ossl_dh_to_der, 0);
- rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0);
rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0);
DEF_OSSL_PKEY_BN(cDH, dh, p);
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index f017cceb4a..ab9ac781e8 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -264,47 +264,6 @@ ossl_dsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dsa.public_key -> aDSA
- *
- * Returns a new DSA instance that carries just the public key information.
- * If the current instance has also private key information, this will no
- * longer be present in the new instance. This feature is helpful for
- * publishing the public key information without leaking any of the private
- * information.
- *
- * === Example
- * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information
- * pub_key = dsa.public_key # has only the public part available
- * pub_key_der = pub_key.to_der # it's safe to publish this
- *
- *
- */
-static VALUE
-ossl_dsa_to_public_key(VALUE self)
-{
- EVP_PKEY *pkey, *pkey_new;
- DSA *dsa;
- VALUE obj;
-
- GetPKeyDSA(self, pkey);
- obj = rb_obj_alloc(rb_obj_class(self));
- GetPKey(obj, pkey_new);
-
-#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
- (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
- dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
-#undef DSAPublicKey_dup
- if (!dsa)
- ossl_raise(eDSAError, "DSAPublicKey_dup");
- if (!EVP_PKEY_assign_DSA(pkey_new, dsa)) {
- DSA_free(dsa);
- ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
- }
- return obj;
-}
-
/*
* call-seq:
* dsa.syssign(string) -> aString
@@ -445,7 +404,6 @@ Init_ossl_dsa(void)
rb_define_alias(cDSA, "to_pem", "export");
rb_define_alias(cDSA, "to_s", "export");
rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0);
- rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0);
rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1);
rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2);
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 7a7e66dbda..1c5476cdcd 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -390,7 +390,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
* data = "Sign me!"
* pkey = OpenSSL::PKey::RSA.new(2048)
* signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256")
- * pub_key = pkey.public_key
+ * pub_key = OpenSSL::PKey.read(pkey.public_to_der)
* puts pub_key.verify_pss("SHA256", signature, data,
* salt_length: :auto, mgf1_hash: "SHA256") # => true
*/
@@ -587,61 +587,6 @@ ossl_rsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * rsa.public_key -> RSA
- *
- * Makes new RSA instance containing the public key from the private key.
- */
-static VALUE
-ossl_rsa_to_public_key(VALUE self)
-{
- EVP_PKEY *pkey, *pkey_new;
- RSA *rsa;
- VALUE obj;
-
- GetPKeyRSA(self, pkey);
- obj = rb_obj_alloc(rb_obj_class(self));
- GetPKey(obj, pkey_new);
-
- rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
- if (!rsa)
- ossl_raise(eRSAError, "RSAPublicKey_dup");
- if (!EVP_PKEY_assign_RSA(pkey_new, rsa)) {
- RSA_free(rsa);
- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
- }
- return obj;
-}
-
-/*
- * TODO: Test me
-
-static VALUE
-ossl_rsa_blinding_on(VALUE self)
-{
- RSA *rsa;
-
- GetRSA(self, rsa);
-
- if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
- ossl_raise(eRSAError, NULL);
- }
- return self;
-}
-
-static VALUE
-ossl_rsa_blinding_off(VALUE self)
-{
- RSA *rsa;
-
- GetRSA(self, rsa);
- RSA_blinding_off(rsa);
-
- return self;
-}
- */
-
/*
* Document-method: OpenSSL::PKey::RSA#set_key
* call-seq:
@@ -712,7 +657,6 @@ Init_ossl_rsa(void)
rb_define_alias(cRSA, "to_pem", "export");
rb_define_alias(cRSA, "to_s", "export");
rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
- rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index d1e68dbc9f..5f8d04e754 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -69,29 +69,28 @@ def test_private
end
def test_new
- key = OpenSSL::PKey::RSA.new 512
- pem = key.public_key.to_pem
- OpenSSL::PKey::RSA.new pem
- assert_equal([], OpenSSL.errors)
- end
+ key = OpenSSL::PKey::RSA.new(512)
+ assert_equal 512, key.n.num_bits
+ assert_equal 65537, key.e
+ assert_not_nil key.d
- def test_new_exponent_default
- assert_equal(65537, OpenSSL::PKey::RSA.new(512).e)
+ # Specify public exponent
+ key2 = OpenSSL::PKey::RSA.new(512, 3)
+ assert_equal 512, key2.n.num_bits
+ assert_equal 3, key2.e
+ assert_not_nil key2.d
end
- def test_new_with_exponent
- 1.upto(30) do |idx|
- e = (2 ** idx) + 1
- key = OpenSSL::PKey::RSA.new(512, e)
- assert_equal(e, key.e)
- end
- end
+ def test_s_generate
+ key1 = OpenSSL::PKey::RSA.generate(512)
+ assert_equal 512, key1.n.num_bits
+ assert_equal 65537, key1.e
- def test_generate
- key = OpenSSL::PKey::RSA.generate(512, 17)
- assert_equal 512, key.n.num_bits
- assert_equal 17, key.e
- assert_not_nil key.d
+ # Specify public exponent
+ key2 = OpenSSL::PKey::RSA.generate(512, 3)
+ assert_equal 512, key2.n.num_bits
+ assert_equal 3, key2.e
+ assert_not_nil key2.d
end
def test_new_break
--
2.32.0
From 2150af0e55b2a25c24f62006e27e0aec3dc81b57 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 10 Jul 2020 14:34:51 +0900
Subject: [PATCH 3/3] pkey/dh, pkey/ec: use EVP_PKEY_check() family
Use EVP_PKEY_param_check() instead of DH_check() if available. Also,
use EVP_PKEY_public_check() instead of EC_KEY_check_key().
EVP_PKEY_*check() is part of the EVP API and is meant to replace those
low-level functions. They were added by OpenSSL 1.1.1. It is currently
not provided by LibreSSL.
---
ext/openssl/extconf.rb | 3 +++
ext/openssl/ossl_pkey_dh.c | 27 +++++++++++++++++++++++----
ext/openssl/ossl_pkey_ec.c | 23 +++++++++++++++++++----
test/openssl/test_pkey_dh.rb | 16 ++++++++++++++++
4 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index b3c6647faf..17d93443fc 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -173,6 +173,9 @@ def find_openssl_library
have_func("EVP_PBE_scrypt")
have_func("SSL_CTX_set_post_handshake_auth")
+# added in 1.1.1
+have_func("EVP_PKEY_check")
+
Logging::message "=== Checking done. ===\n"
create_header
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index a512b209d3..ca782bbe59 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -273,19 +273,38 @@ ossl_dh_get_params(VALUE self)
* Validates the Diffie-Hellman parameters associated with this instance.
* It checks whether a safe prime and a suitable generator are used. If this
* is not the case, +false+ is returned.
+ *
+ * See also the man page EVP_PKEY_param_check(3).
*/
static VALUE
ossl_dh_check_params(VALUE self)
{
+ int ret;
+#ifdef HAVE_EVP_PKEY_CHECK
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pctx;
+
+ GetPKey(self, pkey);
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!pctx)
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
+ ret = EVP_PKEY_param_check(pctx);
+ EVP_PKEY_CTX_free(pctx);
+#else
DH *dh;
int codes;
GetDH(self, dh);
- if (!DH_check(dh, &codes)) {
- return Qfalse;
- }
+ ret = DH_check(dh, &codes) == 1 && codes == 0;
+#endif
- return codes == 0 ? Qtrue : Qfalse;
+ if (ret == 1)
+ return Qtrue;
+ else {
+ /* DH_check_ex() will put error entry on failure */
+ ossl_clear_error();
+ return Qfalse;
+ }
}
/*
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index ecb8305184..829529d4b9 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -443,20 +443,35 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
}
/*
- * call-seq:
- * key.check_key => true
+ * call-seq:
+ * key.check_key => true
*
- * Raises an exception if the key is invalid.
+ * Raises an exception if the key is invalid.
*
- * See the OpenSSL documentation for EC_KEY_check_key()
+ * See also the man page EVP_PKEY_public_check(3).
*/
static VALUE ossl_ec_key_check_key(VALUE self)
{
+#ifdef HAVE_EVP_PKEY_CHECK
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pctx;
+ int ret;
+
+ GetPKey(self, pkey);
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!pctx)
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
+ ret = EVP_PKEY_public_check(pctx);
+ EVP_PKEY_CTX_free(pctx);
+ if (ret != 1)
+ ossl_raise(eECError, "EVP_PKEY_public_check");
+#else
EC_KEY *ec;
GetEC(self, ec);
if (EC_KEY_check_key(ec) != 1)
ossl_raise(eECError, "EC_KEY_check_key");
+#endif
return Qtrue;
}
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 279ce1984c..f80af8f841 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -86,6 +86,22 @@ def test_key_exchange
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
end
+ def test_params_ok?
+ dh0 = Fixtures.pkey("dh1024")
+
+ dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer(dh0.p),
+ OpenSSL::ASN1::Integer(dh0.g)
+ ]))
+ assert_equal(true, dh1.params_ok?)
+
+ dh2 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer(dh0.p + 1),
+ OpenSSL::ASN1::Integer(dh0.g)
+ ]))
+ assert_equal(false, dh2.params_ok?)
+ end
+
def test_dup
dh = Fixtures.pkey("dh1024")
dh2 = dh.dup
--
2.32.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
From a9977ba2f9863e3fb1b2346589ebbca67d80536c Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
Date: Sat, 14 Aug 2021 10:08:19 +0900
Subject: [PATCH] Constified addr2line.c
---
addr2line.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/addr2line.c b/addr2line.c
index 8ee4416650d3..fed1a8da84e5 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -1138,12 +1138,12 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uleb128(reader));
break;
case DW_FORM_ref_addr:
- if (reader->address_size == 4) {
+ if (reader->format == 4) {
set_uint_value(v, read_uint32(&reader->p));
- } else if (reader->address_size == 8) {
+ } else if (reader->format == 8) {
set_uint_value(v, read_uint64(&reader->p));
} else {
- fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ fprintf(stderr,"unknown format:%d", reader->format);
abort();
}
break;

View File

@ -0,0 +1,27 @@
From 912a8dcfc5369d840dcd6bf0f88ee0bac7d902d6 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
Date: Thu, 30 Sep 2021 18:24:37 +0900
Subject: [PATCH] Needs `AC_PROG_CC`
Although `AC_PROG_CC_C99` has been obsolete, `AC_PROG_CC` is not
and the latter is necessary not to make C++ compiler mandatory.
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index b24a8f59b0..c7059ee1ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -203,7 +203,7 @@ rb_test_CXXFLAGS=${CXXFLAGS+yes}
# BSD's ports and MacPorts prefix GNU binutils with 'g'
dnl Seems necessarily in order to add -std=gnu99 option for gcc 4.9.
-m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
+m4_version_prereq([2.70], [AC_PROG_CC], [AC_PROG_CC_C99])
AC_PROG_CXX
AC_PROG_CPP
--
2.31.1

View File

@ -0,0 +1,29 @@
From b4b5eab2a5fd0e9ac62c01102dd26d0a433c5683 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 18 May 2020 02:17:28 +0900
Subject: [PATCH] test/openssl/test_digest: do not test constants for legacy
algorithms
Remove availability test for MD4 and RIPEMD160 as they are considered
legacy and may be missing depending on the compile-time options of
OpenSSL. OpenSSL 3.0 by default disables them.
---
test/openssl/test_digest.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb
index 8d7046e831..84c128c12f 100644
--- a/test/openssl/test_digest.rb
+++ b/test/openssl/test_digest.rb
@@ -54,7 +54,7 @@ def test_reset
end
def test_digest_constants
- %w{MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name|
+ %w{MD5 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name|
assert_not_nil(OpenSSL::Digest.new(name))
klass = OpenSSL::Digest.const_get(name.tr('-', '_'))
assert_not_nil(klass.new)
--
2.32.0

View File

@ -0,0 +1,439 @@
From 9596788bdd2d061bef042485af14262e9fc4020c Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Thu, 13 Aug 2020 23:20:55 +0900
Subject: [PATCH] test/openssl/test_pkcs12: fix test failures with OpenSSL 3.0
OpenSSL's PKCS12_create() by default uses pbewithSHAAnd40BitRC2-CBC for
encryption of the certificates. However, in OpenSSL 3.0, the algorithm
is part of the legacy provider and is not enabled by default.
Specify another algorithm that is still in the default provider for
these test cases.
---
test/openssl/test_pkcs12.rb | 297 ++++++++++++++++++------------------
1 file changed, 149 insertions(+), 148 deletions(-)
diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb
index fdbe753b17..ec676743bc 100644
--- a/test/openssl/test_pkcs12.rb
+++ b/test/openssl/test_pkcs12.rb
@@ -5,6 +5,9 @@
module OpenSSL
class TestPKCS12 < OpenSSL::TestCase
+ DEFAULT_PBE_PKEYS = "PBE-SHA1-3DES"
+ DEFAULT_PBE_CERTS = "PBE-SHA1-3DES"
+
def setup
super
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@@ -14,47 +17,41 @@ def setup
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
- @cacert = issue_cert(ca, Fixtures.pkey("rsa2048"), 1, ca_exts, nil, nil)
+ ca_key = Fixtures.pkey("rsa-1")
+ @cacert = issue_cert(ca, ca_key, 1, ca_exts, nil, nil)
inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA")
- inter_ca_key = OpenSSL::PKey.read <<-_EOS_
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDp7hIG0SFMG/VWv1dBUWziAPrNmkMXJgTCAoB7jffzRtyyN04K
-oq/89HAszTMStZoMigQURfokzKsjpUp8OYCAEsBtt9d5zPndWMz/gHN73GrXk3LT
-ZsxEn7Xv5Da+Y9F/Hx2QZUHarV5cdZixq2NbzWGwrToogOQMh2pxN3Z/0wIDAQAB
-AoGBAJysUyx3olpsGzv3OMRJeahASbmsSKTXVLZvoIefxOINosBFpCIhZccAG6UV
-5c/xCvS89xBw8aD15uUfziw3AuT8QPEtHCgfSjeT7aWzBfYswEgOW4XPuWr7EeI9
-iNHGD6z+hCN/IQr7FiEBgTp6A+i/hffcSdR83fHWKyb4M7TRAkEA+y4BNd668HmC
-G5MPRx25n6LixuBxrNp1umfjEI6UZgEFVpYOg4agNuimN6NqM253kcTR94QNTUs5
-Kj3EhG1YWwJBAO5rUjiOyCNVX2WUQrOMYK/c1lU7fvrkdygXkvIGkhsPoNRzLPeA
-HGJszKtrKD8bNihWpWNIyqKRHfKVD7yXT+kCQGCAhVCIGTRoypcDghwljHqLnysf
-ci0h5ZdPcIqc7ODfxYhFsJ/Rql5ONgYsT5Ig/+lOQAkjf+TRYM4c2xKx2/8CQBvG
-jv6dy70qDgIUgqzONtlmHeYyFzn9cdBO5sShdVYHvRHjFSMEXsosqK9zvW2UqvuK
-FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3
-Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
------END RSA PRIVATE KEY-----
- _EOS_
- @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, Fixtures.pkey("rsa2048"))
+ inter_ca_key = Fixtures.pkey("rsa-2")
+ @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, ca_key)
exts = [
["keyUsage","digitalSignature",true],
["subjectKeyIdentifier","hash",false],
]
ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate")
- @mykey = Fixtures.pkey("rsa1024")
+ @mykey = Fixtures.pkey("rsa-3")
@mycert = issue_cert(ee, @mykey, 3, exts, @inter_cacert, inter_ca_key)
end
- def test_create
+ def test_create_single_key_single_cert
pkcs12 = OpenSSL::PKCS12.create(
"omg",
"hello",
@mykey,
- @mycert
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
- assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mycert, pkcs12.certificate
assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
+
+ der = pkcs12.to_der
+ decoded = OpenSSL::PKCS12.new(der, "omg")
+ assert_equal @mykey.to_der, decoded.key.to_der
+ assert_equal @mycert, decoded.certificate
+ assert_equal [], Array(decoded.ca_certs)
end
def test_create_no_pass
@@ -62,14 +59,17 @@ def test_create_no_pass
nil,
"hello",
@mykey,
- @mycert
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
- assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mycert, pkcs12.certificate
assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
decoded = OpenSSL::PKCS12.new(pkcs12.to_der)
- assert_cert @mycert, decoded.certificate
+ assert_equal @mycert, decoded.certificate
end
def test_create_with_chain
@@ -80,7 +80,9 @@ def test_create_with_chain
"hello",
@mykey,
@mycert,
- chain
+ chain,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
assert_equal chain, pkcs12.ca_certs
end
@@ -95,14 +97,16 @@ def test_create_with_chain_decode
"hello",
@mykey,
@mycert,
- chain
+ chain,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
decoded = OpenSSL::PKCS12.new(pkcs12.to_der, passwd)
assert_equal chain.size, decoded.ca_certs.size
- assert_include_cert @cacert, decoded.ca_certs
- assert_include_cert @inter_cacert, decoded.ca_certs
- assert_cert @mycert, decoded.certificate
+ assert_include decoded.ca_certs, @cacert
+ assert_include decoded.ca_certs, @inter_cacert
+ assert_equal @mycert, decoded.certificate
assert_equal @mykey.to_der, decoded.key.to_der
end
@@ -126,8 +130,8 @@ def test_create_with_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
2048
)
@@ -138,8 +142,8 @@ def test_create_with_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
"omg"
)
end
@@ -152,7 +156,8 @@ def test_create_with_mac_itr
@mykey,
@mycert,
[],
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
nil,
nil,
2048
@@ -165,148 +170,144 @@ def test_create_with_mac_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
nil,
"omg"
)
end
end
- def test_new_with_one_key_and_one_cert
- # generated with:
- # openssl version #=> OpenSSL 1.0.2h 3 May 2016
- # openssl pkcs12 -in <@mycert> -inkey <RSA1024> -export -out <out>
- str = <<~EOF.unpack("m").first
-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
-vyl2WuMdEwQIMWFFphPkIUICAggA
- EOF
- p12 = OpenSSL::PKCS12.new(str, "abc123")
-
- assert_equal @mykey.to_der, p12.key.to_der
- assert_equal @mycert.subject.to_der, p12.certificate.subject.to_der
- assert_equal [], Array(p12.ca_certs)
- end
-
def test_new_with_no_keys
# generated with:
- # openssl pkcs12 -in <@mycert> -nokeys -export -out <out>
+ # openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export
str = <<~EOF.unpack("m").first
-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
+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
+AA==
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
assert_equal nil, p12.key
assert_equal nil, p12.certificate
assert_equal 1, p12.ca_certs.size
- assert_equal @mycert.subject.to_der, p12.ca_certs[0].subject.to_der
+ assert_equal @mycert.subject, p12.ca_certs[0].subject
end
def test_new_with_no_certs
# generated with:
- # openssl pkcs12 -inkey <RSA1024> -nocerts -export -out <out>
+ # openssl pkcs12 -inkey fixtures/openssl/pkey/rsa-1.pem -nocerts -export
str = <<~EOF.unpack("m").first
-MIIDJwIBAzCCAu0GCSqGSIb3DQEHAaCCAt4EggLaMIIC1jCCAtIGCSqGSIb3DQEH
-AaCCAsMEggK/MIICuzCCArcGCyqGSIb3DQEMCgECoIICpjCCAqIwHAYKKoZIhvcN
-AQwBAzAOBAg6AaYnJs84SwICCAAEggKAQzZH+fWSpcQYD1J7PsGSune85A++fLCQ
-V7tacp2iv95GJkxwYmfTP176pJdgs00mceB9UJ/u9EX5nD0djdjjQjwo6sgKjY0q
-cpVhZw8CMxw7kBD2dhtui0zT8z5hy03LePxsjEKsGiSbeVeeGbSfw/I6AAYbv+Uh
-O/YPBGumeHj/D2WKnfsHJLQ9GAV3H6dv5VKYNxjciK7f/JEyZCuUQGIN64QFHDhJ
-7fzLqd/ul3FZzJZO6a+dwvcgux09SKVXDRSeFmRCEX4b486iWhJJVspCo9P2KNne
-ORrpybr3ZSwxyoICmjyo8gj0OSnEfdx9790Ej1takPqSA1wIdSdBLekbZqB0RBQg
-DEuPOsXNo3QFi8ji1vu0WBRJZZSNC2hr5NL6lNR+DKxG8yzDll2j4W4BBIp22mAE
-7QRX7kVxu17QJXQhOUac4Dd1qXmzebP8t6xkAxD9L7BWEN5OdiXWwSWGjVjMBneX
-nYObi/3UT/aVc5WHMHK2BhCI1bwH51E6yZh06d5m0TQpYGUTWDJdWGBSrp3A+8jN
-N2PMQkWBFrXP3smHoTEN4oZC4FWiPsIEyAkQsfKRhcV9lGKl2Xgq54ROTFLnwKoj
-Z3zJScnq9qmNzvVZSMmDLkjLyDq0pxRxGKBvgouKkWY7VFFIwwBIJM39iDJ5NbBY
-i1AQFTRsRSsZrNVPasCXrIq7bhMoJZb/YZOGBLNyJVqKUoYXhtwsajzSq54VlWft
-JxsPayEd4Vi6O9EU1ahnj6qFEZiKFzsicgK2J1Rb8cYagrp0XWjHW0SBn5GVUWCg
-GUokSFG/0JTdeYTo/sQuG4qNgJkOolRjpeI48Fciq5VUWLvVdKioXzAxMCEwCQYF
-Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA==
+MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3
+DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK
+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
+BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
- assert_equal @mykey.to_der, p12.key.to_der
+ assert_equal Fixtures.pkey("rsa-1").to_der, p12.key.to_der
assert_equal nil, p12.certificate
assert_equal [], Array(p12.ca_certs)
end
def test_dup
- p12 = OpenSSL::PKCS12.create("pass", "name", @mykey, @mycert)
+ p12 = OpenSSL::PKCS12.create(
+ "pass",
+ "name",
+ @mykey,
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
+ )
assert_equal p12.to_der, p12.dup.to_der
end
-
- private
- def assert_cert expected, actual
- [
- :subject,
- :issuer,
- :serial,
- :not_before,
- :not_after,
- ].each do |attribute|
- assert_equal expected.send(attribute), actual.send(attribute)
- end
- assert_equal expected.to_der, actual.to_der
- end
-
- def assert_include_cert cert, ary
- der = cert.to_der
- ary.each do |candidate|
- if candidate.to_der == der
- return true
- end
- end
- false
- end
end
end
--
2.32.0

View File

@ -0,0 +1,67 @@
From 10d2216b2f35a31777a099d9f765b0b6ea34a63e Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 18 May 2020 02:35:35 +0900
Subject: [PATCH] test/openssl/test_pkey: use EC keys for
PKey.generate_parameters tests
OpenSSL 3.0 refuses to generate DSA parameters shorter than 2048 bits,
but generating 2048 bits parameters takes very long time. Let's use EC
in these test cases instead.
---
test/openssl/test_pkey.rb | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index 3630458b3c..88a6e04581 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -27,20 +27,16 @@ def test_generic_oid_inspect
end
def test_s_generate_parameters
- # 512 is non-default; 1024 is used if 'dsa_paramgen_bits' is not specified
- # with OpenSSL 1.1.0.
- pkey = OpenSSL::PKey.generate_parameters("DSA", {
- "dsa_paramgen_bits" => 512,
- "dsa_paramgen_q_bits" => 256,
+ pkey = OpenSSL::PKey.generate_parameters("EC", {
+ "ec_paramgen_curve" => "secp384r1",
})
- assert_instance_of OpenSSL::PKey::DSA, pkey
- assert_equal 512, pkey.p.num_bits
- assert_equal 256, pkey.q.num_bits
- assert_equal nil, pkey.priv_key
+ assert_instance_of OpenSSL::PKey::EC, pkey
+ assert_equal "secp384r1", pkey.group.curve_name
+ assert_equal nil, pkey.private_key
# Invalid options are checked
assert_raise(OpenSSL::PKey::PKeyError) {
- OpenSSL::PKey.generate_parameters("DSA", "invalid" => "option")
+ OpenSSL::PKey.generate_parameters("EC", "invalid" => "option")
}
# Parameter generation callback is called
@@ -59,14 +55,13 @@ def test_s_generate_key
# DSA key pair cannot be generated without parameters
OpenSSL::PKey.generate_key("DSA")
}
- pkey_params = OpenSSL::PKey.generate_parameters("DSA", {
- "dsa_paramgen_bits" => 512,
- "dsa_paramgen_q_bits" => 256,
+ pkey_params = OpenSSL::PKey.generate_parameters("EC", {
+ "ec_paramgen_curve" => "secp384r1",
})
pkey = OpenSSL::PKey.generate_key(pkey_params)
- assert_instance_of OpenSSL::PKey::DSA, pkey
- assert_equal 512, pkey.p.num_bits
- assert_not_equal nil, pkey.priv_key
+ assert_instance_of OpenSSL::PKey::EC, pkey
+ assert_equal "secp384r1", pkey.group.curve_name
+ assert_not_equal nil, pkey.private_key
end
def test_hmac_sign_verify
--
2.32.0

View File

@ -0,0 +1,31 @@
From 05fd14aea7eff2a6911a6f529f1237276482c6e7 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 10 Jul 2020 13:56:38 +0900
Subject: [PATCH] test/openssl/test_ssl: relax regex to match OpenSSL's error
message
OpenSSL 3.0 slightly changed the error message for a certificate
verification failure when an untrusted self-signed certificate is found
in the chain.
---
test/openssl/test_ssl.rb | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 6095d545b5..9e9b8b9b69 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -964,7 +964,9 @@ def test_connect_certificate_verify_failed_exception_message
start_server(ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params
- assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) {
+ # OpenSSL <= 1.1.0: "self signed certificate in certificate chain"
+ # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain"
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) {
server_connect(port, ctx)
}
}
--
2.32.0

View File

@ -0,0 +1,265 @@
From 2c6797bc97d7c92284dc3c0ed27f97ace4e5cfb9 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 31 May 2021 11:44:05 +0900
Subject: [PATCH] test/openssl/utils: remove dup_public helper method
It uses deprecated PKey::{RSA,DSA,DH}#set_* methods, which will not
work with OpenSSL 3.0. The same can easily be achieved using
PKey#public_to_der regardless of the key kind.
---
test/openssl/test_pkey_dh.rb | 8 +++++---
test/openssl/test_pkey_dsa.rb | 15 +++++++++++----
test/openssl/test_pkey_ec.rb | 15 +++++++++++----
test/openssl/test_pkey_rsa.rb | 31 +++++++++++++++++--------------
test/openssl/utils.rb | 26 --------------------------
5 files changed, 44 insertions(+), 51 deletions(-)
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index f80af8f841..757704caf6 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -40,12 +40,14 @@ def test_derive_key
def test_DHparams
dh1024 = Fixtures.pkey("dh1024")
+ dh1024params = dh1024.public_key
+
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(dh1024.p),
OpenSSL::ASN1::Integer(dh1024.g)
])
key = OpenSSL::PKey::DH.new(asn1.to_der)
- assert_same_dh dup_public(dh1024), key
+ assert_same_dh dh1024params, key
pem = <<~EOF
-----BEGIN DH PARAMETERS-----
@@ -55,9 +57,9 @@ def test_DHparams
-----END DH PARAMETERS-----
EOF
key = OpenSSL::PKey::DH.new(pem)
- assert_same_dh dup_public(dh1024), key
+ assert_same_dh dh1024params, key
key = OpenSSL::PKey.read(pem)
- assert_same_dh dup_public(dh1024), key
+ assert_same_dh dh1024params, key
assert_equal asn1.to_der, dh1024.to_der
assert_equal pem, dh1024.export
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 147e50176b..0994607f21 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -138,6 +138,8 @@ def test_DSAPrivateKey_encrypted
def test_PUBKEY
dsa512 = Fixtures.pkey("dsa512")
+ dsa512pub = OpenSSL::PKey::DSA.new(dsa512.public_to_der)
+
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("DSA"),
@@ -153,7 +155,7 @@ def test_PUBKEY
])
key = OpenSSL::PKey::DSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_dsa dup_public(dsa512), key
+ assert_same_dsa dsa512pub, key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -166,10 +168,15 @@ def test_PUBKEY
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::DSA.new(pem)
- assert_same_dsa dup_public(dsa512), key
+ assert_same_dsa dsa512pub, key
+
+ assert_equal asn1.to_der, key.to_der
+ assert_equal pem, key.export
- assert_equal asn1.to_der, dup_public(dsa512).to_der
- assert_equal pem, dup_public(dsa512).export
+ assert_equal asn1.to_der, dsa512.public_to_der
+ assert_equal asn1.to_der, key.public_to_der
+ assert_equal pem, dsa512.public_to_pem
+ assert_equal pem, key.public_to_pem
end
def test_read_DSAPublicKey_pem
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index 4b6df0290f..d62f1b5eb8 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -210,6 +210,8 @@ def test_ECPrivateKey_encrypted
def test_PUBKEY
p256 = Fixtures.pkey("p256")
+ p256pub = OpenSSL::PKey::EC.new(p256.public_to_der)
+
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
@@ -221,7 +223,7 @@ def test_PUBKEY
])
key = OpenSSL::PKey::EC.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_ec dup_public(p256), key
+ assert_same_ec p256pub, key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -230,10 +232,15 @@ def test_PUBKEY
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::EC.new(pem)
- assert_same_ec dup_public(p256), key
+ assert_same_ec p256pub, key
+
+ assert_equal asn1.to_der, key.to_der
+ assert_equal pem, key.export
- assert_equal asn1.to_der, dup_public(p256).to_der
- assert_equal pem, dup_public(p256).export
+ assert_equal asn1.to_der, p256.public_to_der
+ assert_equal asn1.to_der, key.public_to_der
+ assert_equal pem, p256.public_to_pem
+ assert_equal pem, key.public_to_pem
end
def test_ec_group
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 5e127f5407..4548bdb2cf 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -201,7 +201,7 @@ def test_sign_verify_pss
def test_encrypt_decrypt
rsapriv = Fixtures.pkey("rsa-1")
- rsapub = dup_public(rsapriv)
+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der)
# Defaults to PKCS #1 v1.5
raw = "data"
@@ -216,7 +216,7 @@ def test_encrypt_decrypt
def test_encrypt_decrypt_legacy
rsapriv = Fixtures.pkey("rsa-1")
- rsapub = dup_public(rsapriv)
+ rsapub = OpenSSL::PKey.read(rsapriv.public_to_der)
# Defaults to PKCS #1 v1.5
raw = "data"
@@ -346,13 +346,15 @@ def test_RSAPrivateKey_encrypted
def test_RSAPublicKey
rsa1024 = Fixtures.pkey("rsa1024")
+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der)
+
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(rsa1024.n),
OpenSSL::ASN1::Integer(rsa1024.e)
])
key = OpenSSL::PKey::RSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_rsa dup_public(rsa1024), key
+ assert_same_rsa rsa1024pub, key
pem = <<~EOF
-----BEGIN RSA PUBLIC KEY-----
@@ -362,11 +364,13 @@ def test_RSAPublicKey
-----END RSA PUBLIC KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem)
- assert_same_rsa dup_public(rsa1024), key
+ assert_same_rsa rsa1024pub, key
end
def test_PUBKEY
rsa1024 = Fixtures.pkey("rsa1024")
+ rsa1024pub = OpenSSL::PKey::RSA.new(rsa1024.public_to_der)
+
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("rsaEncryption"),
@@ -381,7 +385,7 @@ def test_PUBKEY
])
key = OpenSSL::PKey::RSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_rsa dup_public(rsa1024), key
+ assert_same_rsa rsa1024pub, key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -392,10 +396,15 @@ def test_PUBKEY
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem)
- assert_same_rsa dup_public(rsa1024), key
+ assert_same_rsa rsa1024pub, key
+
+ assert_equal asn1.to_der, key.to_der
+ assert_equal pem, key.export
- assert_equal asn1.to_der, dup_public(rsa1024).to_der
- assert_equal pem, dup_public(rsa1024).export
+ assert_equal asn1.to_der, rsa1024.public_to_der
+ assert_equal asn1.to_der, key.public_to_der
+ assert_equal pem, rsa1024.public_to_pem
+ assert_equal pem, key.public_to_pem
end
def test_pem_passwd
@@ -482,12 +491,6 @@ def test_private_encoding_encrypted
assert_same_rsa rsa1024, OpenSSL::PKey.read(pem, "abcdef")
end
- def test_public_encoding
- rsa1024 = Fixtures.pkey("rsa1024")
- assert_equal dup_public(rsa1024).to_der, rsa1024.public_to_der
- assert_equal dup_public(rsa1024).to_pem, rsa1024.public_to_pem
- end
-
def test_dup
key = Fixtures.pkey("rsa1024")
key2 = key.dup
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index c1d737b2ab..f664bd3074 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -313,32 +313,6 @@ def check_component(base, test, keys)
assert_equal base.send(comp), test.send(comp)
}
end
-
- def dup_public(key)
- case key
- when OpenSSL::PKey::RSA
- rsa = OpenSSL::PKey::RSA.new
- rsa.set_key(key.n, key.e, nil)
- rsa
- when OpenSSL::PKey::DSA
- dsa = OpenSSL::PKey::DSA.new
- dsa.set_pqg(key.p, key.q, key.g)
- dsa.set_key(key.pub_key, nil)
- dsa
- when OpenSSL::PKey::DH
- dh = OpenSSL::PKey::DH.new
- dh.set_pqg(key.p, nil, key.g)
- dh
- else
- if defined?(OpenSSL::PKey::EC) && OpenSSL::PKey::EC === key
- ec = OpenSSL::PKey::EC.new(key.group)
- ec.public_key = key.public_key
- ec
- else
- raise "unknown key type"
- end
- end
- end
end
module OpenSSL::Certs
--
2.32.0

951
ruby.spec

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
From bb0f57aeb4de36a3b2b8b8cb01d25b32af0357d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
Date: Wed, 27 Oct 2021 16:28:24 +0200
Subject: [PATCH] Provide distinguished name which will be correctly parsed.
It seems that since ruby openssl 2.1.0 [[1]], the distinguished name
submitted to `OpenSSL::X509::Name.parse` is not correctly parsed if it
does not contain the first slash:
~~~
$ ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
$ gem list | grep openssl
openssl (default: 2.2.0)
$ irb -r openssl
irb(main):001:0> OpenSSL::X509::Name.parse("CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE)
=> "CN = nobody/DC=example"
irb(main):002:0> OpenSSL::X509::Name.parse("/CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE)
=> "CN = nobody, DC = example"
~~~
[1]: https://github.com/ruby/openssl/commit/19c67cd10c57f3ab7b13966c36431ebc3fdd653b
---
lib/rubygems/security.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
index c80639af6d..12de141f36 100644
--- a/lib/rubygems/security.rb
+++ b/lib/rubygems/security.rb
@@ -510,7 +510,7 @@ def self.email_to_name(email_address)
dcs = dcs.split '.'
- name = "CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}"
+ name = "/CN=#{cn}/#{dcs.map {|dc| "DC=#{dc}" }.join '/'}"
OpenSSL::X509::Name.parse name
end
--
2.32.0

View File

@ -0,0 +1,262 @@
From e80e7a3d0b3d72f7af7286b935702b3fab117008 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Wed, 8 Dec 2021 21:12:24 +0100
Subject: [PATCH 1/5] More explicit require
This class does not use `rubygems/deprecate`. It uses
`rubygems/version`, which in turn uses `rubygems/deprecate`. Make this
explicit.
---
lib/rubygems/requirement.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index d2e28fab5b4..9edd6aa7d3c 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-require_relative "deprecate"
+require_relative "version"
##
# A Requirement is a set of one or more version restrictions. It supports a
From 4e46dcc17ee5cabbde43b8a34063b8ab042536f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Wed, 8 Dec 2021 21:17:30 +0100
Subject: [PATCH 2/5] Remove ineffective autoloads
These files are loaded on startup unconditionally, so we can require
them relatively when needed.
---
lib/rubygems.rb | 4 +---
lib/rubygems/specification.rb | 2 ++
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index f803e47628e..b8747409304 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -1310,19 +1310,17 @@ def default_gem_load_paths
autoload :Licenses, File.expand_path('rubygems/util/licenses', __dir__)
autoload :NameTuple, File.expand_path('rubygems/name_tuple', __dir__)
autoload :PathSupport, File.expand_path('rubygems/path_support', __dir__)
- autoload :Platform, File.expand_path('rubygems/platform', __dir__)
autoload :RequestSet, File.expand_path('rubygems/request_set', __dir__)
- autoload :Requirement, File.expand_path('rubygems/requirement', __dir__)
autoload :Resolver, File.expand_path('rubygems/resolver', __dir__)
autoload :Source, File.expand_path('rubygems/source', __dir__)
autoload :SourceList, File.expand_path('rubygems/source_list', __dir__)
autoload :SpecFetcher, File.expand_path('rubygems/spec_fetcher', __dir__)
- autoload :Specification, File.expand_path('rubygems/specification', __dir__)
autoload :Util, File.expand_path('rubygems/util', __dir__)
autoload :Version, File.expand_path('rubygems/version', __dir__)
end
require_relative 'rubygems/exceptions'
+require_relative 'rubygems/specification'
# REFACTOR: This should be pulled out into some kind of hacks file.
begin
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index d3b96491a28..dc5e5ba0138 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -9,6 +9,8 @@
require_relative 'deprecate'
require_relative 'basic_specification'
require_relative 'stub_specification'
+require_relative 'platform'
+require_relative 'requirement'
require_relative 'specification_policy'
require_relative 'util/list'
From 96b6b3e04e8e4fec17f63079a0caf999a2709d71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Wed, 8 Dec 2021 21:45:16 +0100
Subject: [PATCH 3/5] Load `operating_system.rb` customizations before setting
up default gems
It's very common for packagers to configure gem paths in this file, for
example, `Gem.default_dir`. Also, setting up default gems requires these
paths to be set, so that we know which default gems need to be setup.
If we setup default gems before loading `operatin_system.rb`
customizations, the wrong default gems will be setup.
Unfortunately, default gems loaded by `operating_system.rb` can't be
upgraded if we do this, but it seems much of a smaller issue. I wasn't
even fully sure it was the right thing to do when I added that, and it
was not the culprit of the end user issue that led to making that
change.
---
.github/workflows/install-rubygems.yml | 5 ----
lib/rubygems.rb | 32 +++++++++++++-------------
test/rubygems/test_rubygems.rb | 23 ++++++++++++++++++
3 files changed, 39 insertions(+), 21 deletions(-)
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index b8747409304..11474b6554c 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -1323,22 +1323,6 @@ def default_gem_load_paths
require_relative 'rubygems/specification'
# REFACTOR: This should be pulled out into some kind of hacks file.
-begin
- ##
- # Defaults the Ruby implementation wants to provide for RubyGems
-
- require "rubygems/defaults/#{RUBY_ENGINE}"
-rescue LoadError
-end
-
-##
-# Loads the default specs.
-Gem::Specification.load_defaults
-
-require_relative 'rubygems/core_ext/kernel_gem'
-require_relative 'rubygems/core_ext/kernel_require'
-require_relative 'rubygems/core_ext/kernel_warn'
-
begin
##
# Defaults the operating system (or packager) wants to provide for RubyGems.
@@ -1354,3 +1338,19 @@ def default_gem_load_paths
"the problem and ask for help."
raise e.class, msg
end
+
+begin
+ ##
+ # Defaults the Ruby implementation wants to provide for RubyGems
+
+ require "rubygems/defaults/#{RUBY_ENGINE}"
+rescue LoadError
+end
+
+##
+# Loads the default specs.
+Gem::Specification.load_defaults
+
+require_relative 'rubygems/core_ext/kernel_gem'
+require_relative 'rubygems/core_ext/kernel_require'
+require_relative 'rubygems/core_ext/kernel_warn'
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
index 493b9fdf4a3..fa77a299322 100644
--- a/test/rubygems/test_rubygems.rb
+++ b/test/rubygems/test_rubygems.rb
@@ -22,6 +22,29 @@ def test_operating_system_other_exceptions
"the problem and ask for help."
end
+ def test_operating_system_customizing_default_dir
+ pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby'
+ pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby'
+
+ # On a non existing default dir, there should be no gems
+
+ path = util_install_operating_system_rb <<-RUBY
+ module Gem
+ def self.default_dir
+ File.expand_path("foo")
+ end
+ end
+ RUBY
+
+ output = Gem::Util.popen(
+ *ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
+ '-e',
+ "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)",
+ {:err => [:child, :out]}
+ ).strip
+ assert_empty output
+ end
+
private
def util_install_operating_system_rb(content)
From 52cfdd14fd1213a97aac12f01177e27779de9035 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Thu, 9 Dec 2021 06:08:31 +0100
Subject: [PATCH 4/5] Install default fiddle on latest ruby on specs that need
it
Otherwise first OS customizations load and activate that fiddle version,
but then when we change to `Gem.default_dir`, that fiddle version is no
longer there.
---
bundler/spec/commands/clean_spec.rb | 2 +-
bundler/spec/install/gems/standalone_spec.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index ffaf22dbb32..65231b35fac 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -638,7 +638,7 @@ def should_not_have_gems(*gems)
s.executables = "irb"
end
- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
index db16a1b0e13..faefda25f45 100644
--- a/spec/bundler/install/gems/standalone_spec.rb
+++ b/spec/bundler/install/gems/standalone_spec.rb
@@ -113,7 +113,7 @@
skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0"
+ realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0"
necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"]
necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a")
From c6a9c81021092c9157f5616a2bbe1323411a5bf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
Date: Thu, 9 Dec 2021 12:46:23 +0100
Subject: [PATCH 5/5] Resolve symlinks in LOAD_PATH when activating
pre-required default gems
Some double load issues were reported a while ago by OS packagers where
if a gem has been required before rubygems, and then after, rubygems
require would cause a double load.
We avoid this issue by activating the corresponding gem if we detect
that a file in the default LOAD_PATH that belongs to a default gem has
already been required when rubygems registers default gems.
However, the fix does not take into account that the default LOAD_PATH
could potentially include symlinks. This change fixes the same double
load issue described above but for situations where the default
LOAD_PATH includes symlinks.
---
lib/rubygems.rb | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 11474b6554c..b7dda38d522 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -1293,7 +1293,12 @@ def already_loaded?(file)
end
def default_gem_load_paths
- @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1]
+ @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp|
+ expanded = File.expand_path(lp)
+ next expanded unless File.exist?(expanded)
+
+ File.realpath(expanded)
+ end
end
end

View File

@ -9,9 +9,9 @@ module RubyGemsProv
def self.normalize_prerelease(version) def self.normalize_prerelease(version)
if version.prerelease? if version.prerelease?
prerelease = version.version.sub /^#{version.release}\./, '' prerelease = version.version.sub /^#{version.release}\./, ''
"#{version.release}-0.1.#{prerelease}" "#{version.release}~#{prerelease}"
else else
"#{version.release}-1" version.release
end end
end end
end end

View File

@ -35,31 +35,35 @@ module RubyGemsReq
# with RPM .spec file. # with RPM .spec file.
def self.requirement_versions_to_rpm(requirement) def self.requirement_versions_to_rpm(requirement)
self.expand_requirement(requirement.requirements).map do |op, version| self.expand_requirement(requirement.requirements).map do |op, version|
version == Gem::Version.new(0) ? "" : "#{op} #{version}" version == Gem::Version.new(0) ? "" : " #{op} #{version}"
end end
end end
# Compose dependency together with its requirements in RPM rich dependency
# string.
def self.compose_dependency_string(name, requirements)
dependency_strings = requirements.map { |requirement| name + requirement }
dependency_string = dependency_strings.join(' with ')
dependency_string.prepend('(').concat(')') if dependency_strings.length > 1
dependency_string
end
end end
# Report RubyGems dependency, versioned if required. # Report RubyGems dependency, versioned if required.
def self.rubygems_dependency(specification) def self.rubygems_dependency(specification)
Helpers::requirement_versions_to_rpm(specification.required_rubygems_version).each do |requirement| dependency_name = "ruby(rubygems)"
dependency_string = "ruby(rubygems)" requirements = Helpers::requirement_versions_to_rpm(specification.required_rubygems_version)
dependency_string += " #{specification.required_rubygems_version}" if requirement&.length > 0
puts dependency_string puts Helpers::compose_dependency_string(dependency_name, requirements)
end
end end
# Report all gem dependencies including their version. # Report all gem dependencies including their version.
def self.gem_depenencies(specification) def self.gem_depenencies(specification)
specification.runtime_dependencies.each do |dependency| specification.runtime_dependencies.each do |dependency|
dependency_strings = Helpers::requirement_versions_to_rpm(dependency.requirement).map do |requirement| dependency_name = "rubygem(#{dependency.name})"
requirement_string = "rubygem(#{dependency.name})" requirements = Helpers::requirement_versions_to_rpm(dependency.requirement)
requirement_string += " #{requirement}" if requirement&.length > 0
requirement_string puts Helpers::compose_dependency_string(dependency_name, requirements)
end
dependency_string = dependency_strings.join(' with ')
dependency_string.prepend('(').concat(')') if dependency_strings.length > 1
puts dependency_string
end end
end end

View File

@ -1,548 +0,0 @@
diff -Nur ruby-2.5.8/lib/rexml/doctype.rb ruby-2.5.9/lib/rexml/doctype.rb
--- ruby-2.5.8/lib/rexml/doctype.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/lib/rexml/doctype.rb 2021-04-05 11:46:35.000000000 +0000
@@ -7,6 +7,39 @@
require 'rexml/xmltokens'
module REXML
+ class ReferenceWriter
+ def initialize(id_type,
+ public_id_literal,
+ system_literal)
+ @id_type = id_type
+ @public_id_literal = public_id_literal
+ @system_literal = system_literal
+ @default_quote = "\""
+ end
+
+ def write(output)
+ output << " #{@id_type}"
+ if @public_id_literal
+ if @public_id_literal.include?("'")
+ quote = "\""
+ else
+ quote = @default_quote
+ end
+ output << " #{quote}#{@public_id_literal}#{quote}"
+ end
+ if @system_literal
+ if @system_literal.include?("'")
+ quote = "\""
+ elsif @system_literal.include?("\"")
+ quote = "'"
+ else
+ quote = @default_quote
+ end
+ output << " #{quote}#{@system_literal}#{quote}"
+ end
+ end
+ end
+
# Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
# ... >. DOCTYPES can be used to declare the DTD of a document, as well as
# being used to declare entities used in the document.
@@ -50,6 +83,8 @@
super( parent )
@name = first.name
@external_id = first.external_id
+ @long_name = first.instance_variable_get(:@long_name)
+ @uri = first.instance_variable_get(:@uri)
elsif first.kind_of? Array
super( parent )
@name = first[0]
@@ -112,9 +147,12 @@
output << START
output << ' '
output << @name
- output << " #@external_id" if @external_id
- output << " #{@long_name.inspect}" if @long_name
- output << " #{@uri.inspect}" if @uri
+ if @external_id
+ reference_writer = ReferenceWriter.new(@external_id,
+ @long_name,
+ @uri)
+ reference_writer.write(output)
+ end
unless @children.empty?
output << ' ['
@children.each { |child|
@@ -249,9 +287,9 @@
end
def to_s
- notation = "<!NOTATION #{@name} #{@middle}"
- notation << " #{@public.inspect}" if @public
- notation << " #{@system.inspect}" if @system
+ notation = "<!NOTATION #{@name}"
+ reference_writer = ReferenceWriter.new(@middle, @public, @system)
+ reference_writer.write(notation)
notation << ">"
notation
end
diff -Nur ruby-2.5.8/lib/rexml/parsers/baseparser.rb ruby-2.5.9/lib/rexml/parsers/baseparser.rb
--- ruby-2.5.8/lib/rexml/parsers/baseparser.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/lib/rexml/parsers/baseparser.rb 2021-04-05 11:46:35.000000000 +0000
@@ -1,4 +1,7 @@
# frozen_string_literal: false
+
+require "strscan"
+
require 'rexml/parseexception'
require 'rexml/undefinednamespaceexception'
require 'rexml/source'
@@ -32,8 +35,12 @@
COMBININGCHAR = '' # TODO
EXTENDER = '' # TODO
- NCNAME_STR= "[#{LETTER}_:][-[:alnum:]._:#{COMBININGCHAR}#{EXTENDER}]*"
- NAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})"
+ NCNAME_STR= "[#{LETTER}_][-[:alnum:]._#{COMBININGCHAR}#{EXTENDER}]*"
+ QNAME_STR= "(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})"
+ QNAME = /(#{QNAME_STR})/
+
+ # Just for backward compatibility. For example, kramdown uses this.
+ # It's not used in REXML.
UNAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
NAMECHAR = '[\-\w\.:]'
@@ -45,8 +52,7 @@
DOCTYPE_START = /\A\s*<!DOCTYPE\s/um
DOCTYPE_END = /\A\s*\]\s*>/um
- DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
- ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\4/um
+ ATTRIBUTE_PATTERN = /\s*(#{QNAME_STR})\s*=\s*(["'])(.*?)\4/um
COMMENT_START = /\A<!--/u
COMMENT_PATTERN = /<!--(.*?)-->/um
CDATA_START = /\A<!\[CDATA\[/u
@@ -56,15 +62,14 @@
XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>/um
INSTRUCTION_START = /\A<\?/u
INSTRUCTION_PATTERN = /<\?(.*?)(\s+.*?)?\?>/um
- TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{UNAME_STR}\s*=\s*(["']).*?\5)*)\s*(\/)?>/um
- CLOSE_MATCH = /^\s*<\/(#{NAME_STR})\s*>/um
+ TAG_MATCH = /\A<((?>#{QNAME_STR}))/um
+ CLOSE_MATCH = /\A\s*<\/(#{QNAME_STR})\s*>/um
VERSION = /\bversion\s*=\s*["'](.*?)['"]/um
ENCODING = /\bencoding\s*=\s*["'](.*?)['"]/um
STANDALONE = /\bstandalone\s*=\s*["'](.*?)['"]/um
ENTITY_START = /\A\s*<!ENTITY/
- IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u
ELEMENTDECL_START = /\A\s*<!ELEMENT/um
ELEMENTDECL_PATTERN = /\A\s*(<!ELEMENT.*?)>/um
SYSTEMENTITY = /\A\s*(%.*?;)\s*$/um
@@ -78,9 +83,6 @@
ATTDEF_RE = /#{ATTDEF}/
ATTLISTDECL_START = /\A\s*<!ATTLIST/um
ATTLISTDECL_PATTERN = /\A\s*<!ATTLIST\s+#{NAME}(?:#{ATTDEF})*\s*>/um
- NOTATIONDECL_START = /\A\s*<!NOTATION/um
- PUBLIC = /\A\s*<!NOTATION\s+(\w[\-\w]*)\s+(PUBLIC)\s+(["'])(.*?)\3(?:\s+(["'])(.*?)\5)?\s*>/um
- SYSTEM = /\A\s*<!NOTATION\s+(\w[\-\w]*)\s+(SYSTEM)\s+(["'])(.*?)\3\s*>/um
TEXT_PATTERN = /\A([^<]*)/um
@@ -98,6 +100,11 @@
GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
+ NOTATIONDECL_START = /\A\s*<!NOTATION/um
+ EXTERNAL_ID_PUBLIC = /\A\s*PUBLIC\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}\s*/um
+ EXTERNAL_ID_SYSTEM = /\A\s*SYSTEM\s+#{SYSTEMLITERAL}\s*/um
+ PUBLIC_ID = /\A\s*PUBLIC\s+#{PUBIDLITERAL}\s*/um
+
EREFERENCE = /&(?!#{NAME};)/
DEFAULT_ENTITIES = {
@@ -112,7 +119,7 @@
# These are patterns to identify common markup errors, to make the
# error messages more informative.
######################################################################
- MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\s+#{NAME_STR}\s*=\s*[^"']/um
+ MISSING_ATTRIBUTE_QUOTES = /^<#{QNAME_STR}\s+#{QNAME_STR}\s*=\s*[^"']/um
def initialize( source )
self.stream = source
@@ -197,11 +204,9 @@
return [ :end_document ] if empty?
return @stack.shift if @stack.size > 0
#STDERR.puts @source.encoding
- @source.read if @source.buffer.size<2
#STDERR.puts "BUFFER = #{@source.buffer.inspect}"
if @document_status == nil
- #@source.consume( /^\s*/um )
- word = @source.match( /^((?:\s+)|(?:<[^>]*>))/um )
+ word = @source.match( /\A((?:\s+)|(?:<[^>]*>))/um )
word = word[1] unless word.nil?
#STDERR.puts "WORD = #{word.inspect}"
case word
@@ -226,38 +231,49 @@
when INSTRUCTION_START
return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
when DOCTYPE_START
- md = @source.match( DOCTYPE_PATTERN, true )
+ base_error_message = "Malformed DOCTYPE"
+ @source.match(DOCTYPE_START, true)
@nsstack.unshift(curr_ns=Set.new)
- identity = md[1]
- close = md[2]
- identity =~ IDENTITY
- name = $1
- raise REXML::ParseException.new("DOCTYPE is missing a name") if name.nil?
- pub_sys = $2.nil? ? nil : $2.strip
- long_name = $4.nil? ? nil : $4.strip
- uri = $6.nil? ? nil : $6.strip
- args = [ :start_doctype, name, pub_sys, long_name, uri ]
- if close == ">"
+ name = parse_name(base_error_message)
+ if @source.match(/\A\s*\[/um, true)
+ id = [nil, nil, nil]
+ @document_status = :in_doctype
+ elsif @source.match(/\A\s*>/um, true)
+ id = [nil, nil, nil]
@document_status = :after_doctype
- @source.read if @source.buffer.size<2
- md = @source.match(/^\s*/um, true)
- @stack << [ :end_doctype ]
else
- @document_status = :in_doctype
+ id = parse_id(base_error_message,
+ accept_external_id: true,
+ accept_public_id: false)
+ if id[0] == "SYSTEM"
+ # For backward compatibility
+ id[1], id[2] = id[2], nil
+ end
+ if @source.match(/\A\s*\[/um, true)
+ @document_status = :in_doctype
+ elsif @source.match(/\A\s*>/um, true)
+ @document_status = :after_doctype
+ else
+ message = "#{base_error_message}: garbage after external ID"
+ raise REXML::ParseException.new(message, @source)
+ end
+ end
+ args = [:start_doctype, name, *id]
+ if @document_status == :after_doctype
+ @source.match(/\A\s*/um, true)
+ @stack << [ :end_doctype ]
end
return args
- when /^\s+/
+ when /\A\s+/
else
@document_status = :after_doctype
- @source.read if @source.buffer.size<2
- md = @source.match(/\s*/um, true)
if @source.encoding == "UTF-8"
@source.buffer.force_encoding(::Encoding::UTF_8)
end
end
end
if @document_status == :in_doctype
- md = @source.match(/\s*(.*?>)/um)
+ md = @source.match(/\A\s*(.*?>)/um)
case md[1]
when SYSTEMENTITY
match = @source.match( SYSTEMENTITY, true )[1]
@@ -314,33 +330,50 @@
end
return [ :attlistdecl, element, pairs, contents ]
when NOTATIONDECL_START
- md = nil
- if @source.match( PUBLIC )
- md = @source.match( PUBLIC, true )
- vals = [md[1],md[2],md[4],md[6]]
- elsif @source.match( SYSTEM )
- md = @source.match( SYSTEM, true )
- vals = [md[1],md[2],nil,md[4]]
- else
- raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
+ base_error_message = "Malformed notation declaration"
+ unless @source.match(/\A\s*<!NOTATION\s+/um, true)
+ if @source.match(/\A\s*<!NOTATION\s*>/um)
+ message = "#{base_error_message}: name is missing"
+ else
+ message = "#{base_error_message}: invalid declaration name"
+ end
+ raise REXML::ParseException.new(message, @source)
+ end
+ name = parse_name(base_error_message)
+ id = parse_id(base_error_message,
+ accept_external_id: true,
+ accept_public_id: true)
+ unless @source.match(/\A\s*>/um, true)
+ message = "#{base_error_message}: garbage before end >"
+ raise REXML::ParseException.new(message, @source)
end
- return [ :notationdecl, *vals ]
+ return [:notationdecl, name, *id]
when DOCTYPE_END
@document_status = :after_doctype
@source.match( DOCTYPE_END, true )
return [ :end_doctype ]
end
end
+ if @document_status == :after_doctype
+ @source.match(/\A\s*/um, true)
+ end
begin
+ @source.read if @source.buffer.size<2
if @source.buffer[0] == ?<
if @source.buffer[1] == ?/
@nsstack.shift
last_tag = @tags.pop
#md = @source.match_to_consume( '>', CLOSE_MATCH)
md = @source.match( CLOSE_MATCH, true )
- raise REXML::ParseException.new( "Missing end tag for "+
- "'#{last_tag}' (got \"#{md[1]}\")",
- @source) unless last_tag == md[1]
+ if md and !last_tag
+ message = "Unexpected top-level end tag (got '#{md[1]}')"
+ raise REXML::ParseException.new(message, @source)
+ end
+ if md.nil? or last_tag != md[1]
+ message = "Missing end tag for '#{last_tag}'"
+ message << " (got '#{md[1]}')" if md
+ raise REXML::ParseException.new(message, @source)
+ end
return [ :end_element, last_tag ]
elsif @source.buffer[1] == ?!
md = @source.match(/\A(\s*[^>]*>)/um)
@@ -374,40 +407,11 @@
raise REXML::ParseException.new("missing attribute quote", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES )
raise REXML::ParseException.new("malformed XML: missing tag start", @source)
end
- attributes = {}
+ @document_status = :in_element
prefixes = Set.new
prefixes << md[2] if md[2]
@nsstack.unshift(curr_ns=Set.new)
- if md[4].size > 0
- attrs = md[4].scan( ATTRIBUTE_PATTERN )
- raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
- attrs.each do |attr_name, prefix, local_part, quote, value|
- if prefix == "xmlns"
- if local_part == "xml"
- if value != "http://www.w3.org/XML/1998/namespace"
- msg = "The 'xml' prefix must not be bound to any other namespace "+
- "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
- raise REXML::ParseException.new( msg, @source, self )
- end
- elsif local_part == "xmlns"
- msg = "The 'xmlns' prefix must not be declared "+
- "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
- raise REXML::ParseException.new( msg, @source, self)
- end
- curr_ns << local_part
- elsif prefix
- prefixes << prefix unless prefix == "xml"
- end
-
- if attributes.has_key?(attr_name)
- msg = "Duplicate attribute #{attr_name.inspect}"
- raise REXML::ParseException.new(msg, @source, self)
- end
-
- attributes[attr_name] = value
- end
- end
-
+ attributes, closed = parse_attributes(prefixes, curr_ns)
# Verify that all of the prefixes have been defined
for prefix in prefixes
unless @nsstack.find{|k| k.member?(prefix)}
@@ -415,7 +419,7 @@
end
end
- if md[6]
+ if closed
@closed = md[1]
@nsstack.shift
else
@@ -508,6 +512,169 @@
return false if /\AUTF-16\z/i =~ xml_declaration_encoding
true
end
+
+ def parse_name(base_error_message)
+ md = @source.match(/\A\s*#{NAME}/um, true)
+ unless md
+ if @source.match(/\A\s*\S/um)
+ message = "#{base_error_message}: invalid name"
+ else
+ message = "#{base_error_message}: name is missing"
+ end
+ raise REXML::ParseException.new(message, @source)
+ end
+ md[1]
+ end
+
+ def parse_id(base_error_message,
+ accept_external_id:,
+ accept_public_id:)
+ if accept_external_id and (md = @source.match(EXTERNAL_ID_PUBLIC, true))
+ pubid = system = nil
+ pubid_literal = md[1]
+ pubid = pubid_literal[1..-2] if pubid_literal # Remove quote
+ system_literal = md[2]
+ system = system_literal[1..-2] if system_literal # Remove quote
+ ["PUBLIC", pubid, system]
+ elsif accept_public_id and (md = @source.match(PUBLIC_ID, true))
+ pubid = system = nil
+ pubid_literal = md[1]
+ pubid = pubid_literal[1..-2] if pubid_literal # Remove quote
+ ["PUBLIC", pubid, nil]
+ elsif accept_external_id and (md = @source.match(EXTERNAL_ID_SYSTEM, true))
+ system = nil
+ system_literal = md[1]
+ system = system_literal[1..-2] if system_literal # Remove quote
+ ["SYSTEM", nil, system]
+ else
+ details = parse_id_invalid_details(accept_external_id: accept_external_id,
+ accept_public_id: accept_public_id)
+ message = "#{base_error_message}: #{details}"
+ raise REXML::ParseException.new(message, @source)
+ end
+ end
+
+ def parse_id_invalid_details(accept_external_id:,
+ accept_public_id:)
+ public = /\A\s*PUBLIC/um
+ system = /\A\s*SYSTEM/um
+ if (accept_external_id or accept_public_id) and @source.match(/#{public}/um)
+ if @source.match(/#{public}(?:\s+[^'"]|\s*[\[>])/um)
+ return "public ID literal is missing"
+ end
+ unless @source.match(/#{public}\s+#{PUBIDLITERAL}/um)
+ return "invalid public ID literal"
+ end
+ if accept_public_id
+ if @source.match(/#{public}\s+#{PUBIDLITERAL}\s+[^'"]/um)
+ return "system ID literal is missing"
+ end
+ unless @source.match(/#{public}\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}/um)
+ return "invalid system literal"
+ end
+ "garbage after system literal"
+ else
+ "garbage after public ID literal"
+ end
+ elsif accept_external_id and @source.match(/#{system}/um)
+ if @source.match(/#{system}(?:\s+[^'"]|\s*[\[>])/um)
+ return "system literal is missing"
+ end
+ unless @source.match(/#{system}\s+#{SYSTEMLITERAL}/um)
+ return "invalid system literal"
+ end
+ "garbage after system literal"
+ else
+ unless @source.match(/\A\s*(?:PUBLIC|SYSTEM)\s/um)
+ return "invalid ID type"
+ end
+ "ID type is missing"
+ end
+ end
+
+ def parse_attributes(prefixes, curr_ns)
+ attributes = {}
+ closed = false
+ match_data = @source.match(/^(.*?)(\/)?>/um, true)
+ if match_data.nil?
+ message = "Start tag isn't ended"
+ raise REXML::ParseException.new(message, @source)
+ end
+
+ raw_attributes = match_data[1]
+ closed = !match_data[2].nil?
+ return attributes, closed if raw_attributes.nil?
+ return attributes, closed if raw_attributes.empty?
+
+ scanner = StringScanner.new(raw_attributes)
+ until scanner.eos?
+ if scanner.scan(/\s+/)
+ break if scanner.eos?
+ end
+
+ pos = scanner.pos
+ loop do
+ break if scanner.scan(ATTRIBUTE_PATTERN)
+ unless scanner.scan(QNAME)
+ message = "Invalid attribute name: <#{scanner.rest}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ name = scanner[0]
+ unless scanner.scan(/\s*=\s*/um)
+ message = "Missing attribute equal: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ quote = scanner.scan(/['"]/)
+ unless quote
+ message = "Missing attribute value start quote: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ unless scanner.scan(/.*#{Regexp.escape(quote)}/um)
+ match_data = @source.match(/^(.*?)(\/)?>/um, true)
+ if match_data
+ scanner << "/" if closed
+ scanner << ">"
+ scanner << match_data[1]
+ scanner.pos = pos
+ closed = !match_data[2].nil?
+ next
+ end
+ message =
+ "Missing attribute value end quote: <#{name}>: <#{quote}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+ end
+ name = scanner[1]
+ prefix = scanner[2]
+ local_part = scanner[3]
+ # quote = scanner[4]
+ value = scanner[5]
+ if prefix == "xmlns"
+ if local_part == "xml"
+ if value != "http://www.w3.org/XML/1998/namespace"
+ msg = "The 'xml' prefix must not be bound to any other namespace "+
+ "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
+ raise REXML::ParseException.new( msg, @source, self )
+ end
+ elsif local_part == "xmlns"
+ msg = "The 'xmlns' prefix must not be declared "+
+ "(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
+ raise REXML::ParseException.new( msg, @source, self)
+ end
+ curr_ns << local_part
+ elsif prefix
+ prefixes << prefix unless prefix == "xml"
+ end
+
+ if attributes.has_key?(name)
+ msg = "Duplicate attribute #{name.inspect}"
+ raise REXML::ParseException.new(msg, @source, self)
+ end
+
+ attributes[name] = value
+ end
+ return attributes, closed
+ end
end
end
end
diff -Nur ruby-2.5.8/lib/rexml/rexml.rb ruby-2.5.9/lib/rexml/rexml.rb
--- ruby-2.5.8/lib/rexml/rexml.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/lib/rexml/rexml.rb 2021-04-05 11:46:35.000000000 +0000
@@ -24,8 +24,8 @@
module REXML
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
DATE = "2008/019"
- VERSION = "3.1.7.3"
- REVISION = %w$Revision: 53141 $[1] || ''
+ VERSION = "3.1.7.4"
+ REVISION = %w$Revision: 67937 $[1] || ''
Copyright = COPYRIGHT
Version = VERSION

View File

@ -1,775 +0,0 @@
diff -Nur ruby-2.5.8/test/rexml/parse/test_document_type_declaration.rb ruby-2.5.9/test/rexml/parse/test_document_type_declaration.rb
--- ruby-2.5.8/test/rexml/parse/test_document_type_declaration.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/parse/test_document_type_declaration.rb 2021-04-05 11:46:35.000000000 +0000
@@ -5,17 +5,187 @@
module REXMLTests
class TestParseDocumentTypeDeclaration < Test::Unit::TestCase
private
- def xml(internal_subset)
- <<-XML
-<!DOCTYPE r SYSTEM "urn:x-rexml:test" [
-#{internal_subset}
-]>
+ def parse(doctype)
+ REXML::Document.new(<<-XML).doctype
+#{doctype}
<r/>
XML
end
- def parse(internal_subset)
- REXML::Document.new(xml(internal_subset)).doctype
+ class TestName < self
+ def test_valid
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r>
+ DOCTYPE
+ assert_equal("r", doctype.name)
+ end
+
+ def test_garbage_plus_before_name_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE +
+r SYSTEM "urn:x-rexml:test" [
+]>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: invalid name
+Line: 5
+Position: 51
+Last 80 unconsumed characters:
++ r SYSTEM "urn:x-rexml:test" [ ]> <r/>
+ DETAIL
+ end
+ end
+
+ class TestExternalID < self
+ class TestSystem < self
+ def test_left_bracket_in_system_literal
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:[test" [
+]>
+ DOCTYPE
+ assert_equal([
+ "r",
+ "SYSTEM",
+ nil,
+ "urn:x-rexml:[test",
+ ],
+ [
+ doctype.name,
+ doctype.external_id,
+ doctype.public,
+ doctype.system,
+ ])
+ end
+
+ def test_greater_than_in_system_literal
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:>test" [
+]>
+ DOCTYPE
+ assert_equal([
+ "r",
+ "SYSTEM",
+ nil,
+ "urn:x-rexml:>test",
+ ],
+ [
+ doctype.name,
+ doctype.external_id,
+ doctype.public,
+ doctype.system,
+ ])
+ end
+
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: system literal is missing
+Line: 3
+Position: 26
+Last 80 unconsumed characters:
+ SYSTEM> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM 'r.dtd'x'>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: garbage after external ID
+Line: 3
+Position: 36
+Last 80 unconsumed characters:
+x'> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM 'r".dtd'>
+ DOCTYPE
+ assert_equal("r\".dtd", doctype.system)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "r'.dtd">
+ DOCTYPE
+ assert_equal("r'.dtd", doctype.system)
+ end
+ end
+
+ class TestPublic < self
+ class TestPublicIDLiteral < self
+ def test_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'double quote " is invalid' "r.dtd">
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: invalid public ID literal
+Line: 3
+Position: 62
+Last 80 unconsumed characters:
+ PUBLIC 'double quote " is invalid' "r.dtd"> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'public-id-literal' "r.dtd">
+ DOCTYPE
+ assert_equal("public-id-literal", doctype.public)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public'-id-literal" "r.dtd">
+ DOCTYPE
+ assert_equal("public'-id-literal", doctype.public)
+ end
+ end
+
+ class TestSystemLiteral < self
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'public-id-literal' 'system-literal'x'>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: garbage after external ID
+Line: 3
+Position: 65
+Last 80 unconsumed characters:
+x'> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public-id-literal" 'system"-literal'>
+ DOCTYPE
+ assert_equal("system\"-literal", doctype.system)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public-id-literal" "system'-literal">
+ DOCTYPE
+ assert_equal("system'-literal", doctype.system)
+ end
+ end
+ end
end
class TestMixed < self
@@ -45,6 +215,15 @@
assert_equal([REXML::NotationDecl, REXML::AttlistDecl],
doctype.children.collect(&:class))
end
+
+ private
+ def parse(internal_subset)
+ super(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:test" [
+#{internal_subset}
+]>
+ DOCTYPE
+ end
end
end
end
diff -Nur ruby-2.5.8/test/rexml/parse/test_element.rb ruby-2.5.9/test/rexml/parse/test_element.rb
--- ruby-2.5.8/test/rexml/parse/test_element.rb 1970-01-01 00:00:00.000000000 +0000
+++ ruby-2.5.9/test/rexml/parse/test_element.rb 2021-04-05 11:46:35.000000000 +0000
@@ -0,0 +1,77 @@
+require "test/unit"
+require "rexml/document"
+
+module REXMLTests
+ class TestParseElement < Test::Unit::TestCase
+ def parse(xml)
+ REXML::Document.new(xml)
+ end
+
+ class TestInvalid < self
+ def test_top_level_end_tag
+ exception = assert_raise(REXML::ParseException) do
+ parse("</a>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Unexpected top-level end tag (got 'a')
+Line: 1
+Position: 4
+Last 80 unconsumed characters:
+
+ DETAIL
+ end
+
+ def test_no_end_tag
+ exception = assert_raise(REXML::ParseException) do
+ parse("<a></")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Missing end tag for 'a'
+Line: 1
+Position: 5
+Last 80 unconsumed characters:
+</
+ DETAIL
+ end
+
+ def test_empty_namespace_attribute_name
+ exception = assert_raise(REXML::ParseException) do
+ parse("<x :a=\"\"></x>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Invalid attribute name: <:a="">
+Line: 1
+Position: 13
+Last 80 unconsumed characters:
+
+ DETAIL
+ end
+
+ def test_garbage_less_than_before_root_element_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse("<\n<x/>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+malformed XML: missing tag start
+Line: 2
+Position: 6
+Last 80 unconsumed characters:
+< <x/>
+ DETAIL
+ end
+
+ def test_garbage_less_than_slash_before_end_tag_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse("<x></\n</x>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Missing end tag for 'x'
+Line: 2
+Position: 10
+Last 80 unconsumed characters:
+</ </x>
+ DETAIL
+ end
+ end
+ end
+end
diff -Nur ruby-2.5.8/test/rexml/parse/test_notation_declaration.rb ruby-2.5.9/test/rexml/parse/test_notation_declaration.rb
--- ruby-2.5.8/test/rexml/parse/test_notation_declaration.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/parse/test_notation_declaration.rb 2021-04-05 11:46:35.000000000 +0000
@@ -23,10 +23,100 @@
doctype = parse("<!NOTATION name PUBLIC 'urn:public-id'>")
assert_equal("name", doctype.notation("name").name)
end
+
+ def test_no_name
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: name is missing
+Line: 5
+Position: 72
+Last 80 unconsumed characters:
+ <!NOTATION> ]> <r/>
+ DETAIL
+ end
+
+ def test_invalid_name
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION '>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid name
+Line: 5
+Position: 74
+Last 80 unconsumed characters:
+'> ]> <r/>
+ DETAIL
+ end
+
+ def test_no_id_type
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid ID type
+Line: 5
+Position: 77
+Last 80 unconsumed characters:
+> ]> <r/>
+ DETAIL
+ end
+
+ def test_invalid_id_type
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name INVALID>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid ID type
+Line: 5
+Position: 85
+Last 80 unconsumed characters:
+ INVALID> ]> <r/>
+ DETAIL
+ end
end
class TestExternalID < self
class TestSystem < self
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name SYSTEM>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: system literal is missing
+Line: 5
+Position: 84
+Last 80 unconsumed characters:
+ SYSTEM> ]> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name SYSTEM 'system-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 103
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name SYSTEM 'system-literal'>
@@ -44,6 +134,21 @@
class TestPublic < self
class TestPublicIDLiteral < self
+ def test_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'double quote " is invalid' "system-literal">
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid public ID literal
+Line: 5
+Position: 129
+Last 80 unconsumed characters:
+ PUBLIC 'double quote " is invalid' "system-literal"> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name PUBLIC 'public-id-literal' "system-literal">
@@ -60,6 +165,21 @@
end
class TestSystemLiteral < self
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal' 'system-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 123
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name PUBLIC "public-id-literal" 'system-literal'>
@@ -96,5 +216,66 @@
end
end
end
+
+ class TestPublicID < self
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: public ID literal is missing
+Line: 5
+Position: 84
+Last 80 unconsumed characters:
+ PUBLIC> ]> <r/>
+ DETAIL
+ end
+
+ def test_literal_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'double quote " is invalid in PubidLiteral'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid public ID literal
+Line: 5
+Position: 128
+Last 80 unconsumed characters:
+ PUBLIC 'double quote \" is invalid in PubidLiteral'> ]> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 106
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
+ def test_literal_single_quote
+ doctype = parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal'>
+ INTERNAL_SUBSET
+ assert_equal("public-id-literal", doctype.notation("name").public)
+ end
+
+ def test_literal_double_quote
+ doctype = parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC "public-id-literal">
+ INTERNAL_SUBSET
+ assert_equal("public-id-literal", doctype.notation("name").public)
+ end
+ end
end
end
diff -Nur ruby-2.5.8/test/rexml/parser/test_tree.rb ruby-2.5.9/test/rexml/parser/test_tree.rb
--- ruby-2.5.8/test/rexml/parser/test_tree.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/parser/test_tree.rb 2021-04-05 11:46:35.000000000 +0000
@@ -12,7 +12,7 @@
parse(xml)
end
assert_equal(<<-MESSAGE, exception.to_s)
-Missing end tag for 'root' (got "not-root")
+Missing end tag for 'root' (got 'not-root')
Line: 1
Position: #{xml.bytesize}
Last 80 unconsumed characters:
diff -Nur ruby-2.5.8/test/rexml/parser/test_ultra_light.rb ruby-2.5.9/test/rexml/parser/test_ultra_light.rb
--- ruby-2.5.8/test/rexml/parser/test_ultra_light.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/parser/test_ultra_light.rb 2021-04-05 11:46:35.000000000 +0000
@@ -16,7 +16,6 @@
nil,
[:entitydecl, "name", "value"]
],
- [:text, "\n"],
[:start_element, :parent, "root", {}],
[:text, "\n"],
],
diff -Nur ruby-2.5.8/test/rexml/test_core.rb ruby-2.5.9/test/rexml/test_core.rb
--- ruby-2.5.8/test/rexml/test_core.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/test_core.rb 2021-04-05 11:46:35.000000000 +0000
@@ -1,4 +1,4 @@
-# coding: binary
+# coding: utf-8
# frozen_string_literal: false
require_relative "rexml_test_utils"
@@ -995,7 +995,7 @@
document.write(s)
## XML Doctype
- str = '<!DOCTYPE foo "bar">'
+ str = '<!DOCTYPE foo SYSTEM "bar">'
source = REXML::Source.new(str)
doctype = REXML::DocType.new(source)
document.add(doctype)
@@ -1274,14 +1274,15 @@
def test_ticket_21
src = "<foo bar=value/>"
- assert_raise( ParseException, "invalid XML should be caught" ) {
+ exception = assert_raise(ParseException) do
Document.new(src)
- }
- begin
- Document.new(src)
- rescue
- assert_match( /missing attribute quote/, $!.message )
end
+ assert_equal(<<-DETAIL, exception.to_s)
+Missing attribute value start quote: <bar>
+Line: 1
+Position: 16
+Last 80 unconsumed characters:
+ DETAIL
end
def test_ticket_63
diff -Nur ruby-2.5.8/test/rexml/test_doctype.rb ruby-2.5.9/test/rexml/test_doctype.rb
--- ruby-2.5.8/test/rexml/test_doctype.rb 2020-03-31 12:15:56.000000000 +0000
+++ ruby-2.5.9/test/rexml/test_doctype.rb 2021-04-05 11:46:35.000000000 +0000
@@ -4,65 +4,111 @@
module REXMLTests
class TestDocTypeAccessor < Test::Unit::TestCase
-
def setup
@sysid = "urn:x-test:sysid1"
- @notid1 = "urn:x-test:notation1"
- @notid2 = "urn:x-test:notation2"
- document_string1 = <<-"XMLEND"
- <!DOCTYPE r SYSTEM "#{@sysid}" [
- <!NOTATION n1 SYSTEM "#{@notid1}">
- <!NOTATION n2 SYSTEM "#{@notid2}">
+ @notation_id1 = "urn:x-test:notation1"
+ @notation_id2 = "urn:x-test:notation2"
+ xml_system = <<-XML
+ <!DOCTYPE root SYSTEM "#{@sysid}" [
+ <!NOTATION n1 SYSTEM "#{@notation_id1}">
+ <!NOTATION n2 SYSTEM "#{@notation_id2}">
]>
- <r/>
- XMLEND
- @doctype1 = REXML::Document.new(document_string1).doctype
+ <root/>
+ XML
+ @doc_type_system = REXML::Document.new(xml_system).doctype
@pubid = "TEST_ID"
- document_string2 = <<-"XMLEND"
- <!DOCTYPE r PUBLIC "#{@pubid}">
- <r/>
- XMLEND
- @doctype2 = REXML::Document.new(document_string2).doctype
-
- document_string3 = <<-"XMLEND"
- <!DOCTYPE r PUBLIC "#{@pubid}" "#{@sysid}">
- <r/>
- XMLEND
- @doctype3 = REXML::Document.new(document_string3).doctype
-
+ xml_public_system = <<-XML
+ <!DOCTYPE root PUBLIC "#{@pubid}" "#{@sysid}">
+ <root/>
+ XML
+ @doc_type_public_system = REXML::Document.new(xml_public_system).doctype
end
def test_public
- assert_equal(nil, @doctype1.public)
- assert_equal(@pubid, @doctype2.public)
- assert_equal(@pubid, @doctype3.public)
+ assert_equal([
+ nil,
+ @pubid,
+ ],
+ [
+ @doc_type_system.public,
+ @doc_type_public_system.public,
+ ])
+ end
+
+ def test_to_s
+ assert_equal("<!DOCTYPE root PUBLIC \"#{@pubid}\" \"#{@sysid}\">",
+ @doc_type_public_system.to_s)
end
def test_system
- assert_equal(@sysid, @doctype1.system)
- assert_equal(nil, @doctype2.system)
- assert_equal(@sysid, @doctype3.system)
+ assert_equal([
+ @sysid,
+ @sysid,
+ ],
+ [
+ @doc_type_system.system,
+ @doc_type_public_system.system,
+ ])
end
def test_notation
- assert_equal(@notid1, @doctype1.notation("n1").system)
- assert_equal(@notid2, @doctype1.notation("n2").system)
+ assert_equal([
+ @notation_id1,
+ @notation_id2,
+ ],
+ [
+ @doc_type_system.notation("n1").system,
+ @doc_type_system.notation("n2").system,
+ ])
end
def test_notations
- notations = @doctype1.notations
- assert_equal(2, notations.length)
- assert_equal(@notid1, find_notation(notations, "n1").system)
- assert_equal(@notid2, find_notation(notations, "n2").system)
+ notations = @doc_type_system.notations
+ assert_equal([
+ @notation_id1,
+ @notation_id2,
+ ],
+ notations.collect(&:system))
end
+ end
- def find_notation(notations, name)
- notations.find { |notation|
- name == notation.name
- }
+ class TestDocType < Test::Unit::TestCase
+ class TestExternalID < self
+ class TestSystem < self
+ class TestSystemLiteral < self
+ def test_to_s
+ doctype = REXML::DocType.new(["root", "SYSTEM", nil, "root.dtd"])
+ assert_equal("<!DOCTYPE root SYSTEM \"root.dtd\">",
+ doctype.to_s)
+ end
+ end
+ end
+
+ class TestPublic < self
+ class TestPublicIDLiteral < self
+ def test_to_s
+ doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root.dtd"])
+ assert_equal("<!DOCTYPE root PUBLIC \"pub\" \"root.dtd\">",
+ doctype.to_s)
+ end
+ end
+
+ class TestSystemLiteral < self
+ def test_to_s
+ doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root.dtd"])
+ assert_equal("<!DOCTYPE root PUBLIC \"pub\" \"root.dtd\">",
+ doctype.to_s)
+ end
+
+ def test_to_s_double_quote
+ doctype = REXML::DocType.new(["root", "PUBLIC", "pub", "root\".dtd"])
+ assert_equal("<!DOCTYPE root PUBLIC \"pub\" 'root\".dtd'>",
+ doctype.to_s)
+ end
+ end
+ end
end
-
end
class TestNotationDeclPublic < Test::Unit::TestCase
@@ -77,11 +123,26 @@
decl(@id, nil).to_s)
end
+ def test_to_s_pubid_literal_include_apostrophe
+ assert_equal("<!NOTATION #{@name} PUBLIC \"#{@id}'\">",
+ decl("#{@id}'", nil).to_s)
+ end
+
def test_to_s_with_uri
assert_equal("<!NOTATION #{@name} PUBLIC \"#{@id}\" \"#{@uri}\">",
decl(@id, @uri).to_s)
end
+ def test_to_s_system_literal_include_apostrophe
+ assert_equal("<!NOTATION #{@name} PUBLIC \"#{@id}\" \"system'literal\">",
+ decl(@id, "system'literal").to_s)
+ end
+
+ def test_to_s_system_literal_include_double_quote
+ assert_equal("<!NOTATION #{@name} PUBLIC \"#{@id}\" 'system\"literal'>",
+ decl(@id, "system\"literal").to_s)
+ end
+
private
def decl(id, uri)
REXML::NotationDecl.new(@name, "PUBLIC", id, uri)
@@ -99,9 +160,19 @@
decl(@id).to_s)
end
+ def test_to_s_include_apostrophe
+ assert_equal("<!NOTATION #{@name} SYSTEM \"#{@id}'\">",
+ decl("#{@id}'").to_s)
+ end
+
+ def test_to_s_include_double_quote
+ assert_equal("<!NOTATION #{@name} SYSTEM '#{@id}\"'>",
+ decl("#{@id}\"").to_s)
+ end
+
private
def decl(id)
- REXML::NotationDecl.new(@name, "SYSTEM", id, nil)
+ REXML::NotationDecl.new(@name, "SYSTEM", nil, id)
end
end
end