From 9eda3cf4230cc8e31aaa6a6baea164d5bd515323 Mon Sep 17 00:00:00 2001 From: Erim Icel Date: Sun, 27 Jul 2025 14:03:54 +0100 Subject: [PATCH 1/4] Add test for `String#byteslice` with multibyte characters --- test/ruby/test_string.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 138756eac5fd61..e2d0c359cbf38a 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2481,7 +2481,6 @@ def test_unpack i & integer\\ L & unsigned long\\ l & long\\ - m & string encoded in base64 (uuencoded)\\ N & long, network (big-endian) byte order\\ n & short, network (big-endian) byte-order\\ @@ -2493,8 +2492,7 @@ def test_unpack v & short, little-endian byte order\\ X & back up a byte\\ x & null byte\\ - Z & ASCII string (null padded, count is width)\\ -" + Z & ASCII string (null padded, count is width)\\" =end end @@ -2845,13 +2843,15 @@ def test_substr_negative_begin assert_equal("\u3042", ("\u3042" * 100)[-1]) end -=begin def test_compare_different_encoding_string s1 = S("\xff".force_encoding("UTF-8")) s2 = S("\xff".force_encoding("ISO-2022-JP")) assert_equal([-1, 1], [s1 <=> s2, s2 <=> s1].sort) + + s3 = S("あ".force_encoding("UTF-16LE")) + s4 = S("a".force_encoding("IBM437")) + assert_equal([-1, 1], [s3 <=> s4, s4 <=> s3].sort) end -=end def test_casecmp assert_equal(0, S("FoO").casecmp("fOO")) @@ -2953,7 +2953,6 @@ def test_lstrip_bang s5 = S("\u0000\u3042") assert_equal("\u3042", s5.lstrip!) assert_equal("\u3042", s5) - end def test_delete_prefix_type_error @@ -3321,6 +3320,11 @@ def test_byteslice assert_equal(u("\x82")+("\u3042"*9), S("\u3042"*10).byteslice(2, 28)) + assert_equal("\xE3", S("こんにちは").byteslice(0)) + assert_equal("こんにちは", S("こんにちは").byteslice(0, 15)) + assert_equal("こ", S("こんにちは").byteslice(0, 3)) + assert_equal("は", S("こんにちは").byteslice(12, 15)) + bug7954 = '[ruby-dev:47108]' assert_equal(false, S("\u3042").byteslice(0, 2).valid_encoding?, bug7954) assert_equal(false, ("\u3042"*10).byteslice(0, 20).valid_encoding?, bug7954) From ec01cd9bbbaf3e6f324e0a6769b8383857d2bc07 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 27 Jul 2025 22:56:10 +0900 Subject: [PATCH 2/4] Revert "[ruby/openssl] x509: disallow ossl_x509{,attr,crl,ext,revoked,name}*_new(NULL)" This reverts commit 4e8bbb07dd4936b97a6b39d54a6977a107518e1f. It broke RubyGems tests: https://rubyci.s3.amazonaws.com/debian/ruby-master/log/20250727T123003Z.fail.html.gz OpenSSL::X509::StoreContext#current_cert incorrectly calls ossl_x509_new() with NULL to create a bogus Certificate object, and a test case in RubyGems relies on it. This will be reapplied when both are fixed. --- ext/openssl/ossl_x509attr.c | 11 ++++++++--- ext/openssl/ossl_x509cert.c | 11 ++++++++--- ext/openssl/ossl_x509crl.c | 5 ++--- ext/openssl/ossl_x509ext.c | 11 ++++++++--- ext/openssl/ossl_x509name.c | 11 ++++++++--- ext/openssl/ossl_x509revoked.c | 11 ++++++++--- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index d983af59686946..3f6b89bdde5af3 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -54,9 +54,14 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr) VALUE obj; obj = NewX509Attr(cX509Attr); - new = X509_ATTRIBUTE_dup(attr); - if (!new) - ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); + if (!attr) { + new = X509_ATTRIBUTE_new(); + } else { + new = X509_ATTRIBUTE_dup(attr); + } + if (!new) { + ossl_raise(eX509AttrError, NULL); + } SetX509Attr(obj, new); return obj; diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 30e3c617531bde..ecf42d7d43e6d2 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -54,9 +54,14 @@ ossl_x509_new(X509 *x509) VALUE obj; obj = NewX509(cX509Cert); - new = X509_dup(x509); - if (!new) - ossl_raise(eX509CertError, "X509_dup"); + if (!x509) { + new = X509_new(); + } else { + new = X509_dup(x509); + } + if (!new) { + ossl_raise(eX509CertError, NULL); + } SetX509(obj, new); return obj; diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index 52174d1711487b..135dfe3d758d18 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -64,9 +64,8 @@ ossl_x509crl_new(X509_CRL *crl) VALUE obj; obj = NewX509CRL(cX509CRL); - tmp = X509_CRL_dup(crl); - if (!tmp) - ossl_raise(eX509CRLError, "X509_CRL_dup"); + tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new(); + if(!tmp) ossl_raise(eX509CRLError, NULL); SetX509CRL(obj, tmp); return obj; diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 01aa3a8f51cd17..9b0d9aa651977d 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -68,9 +68,14 @@ ossl_x509ext_new(X509_EXTENSION *ext) VALUE obj; obj = NewX509Ext(cX509Ext); - new = X509_EXTENSION_dup(ext); - if (!new) - ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); + if (!ext) { + new = X509_EXTENSION_new(); + } else { + new = X509_EXTENSION_dup(ext); + } + if (!new) { + ossl_raise(eX509ExtError, NULL); + } SetX509Ext(obj, new); return obj; diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 7d0fd35247f5cb..b3791aefa38826 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -59,9 +59,14 @@ ossl_x509name_new(X509_NAME *name) VALUE obj; obj = NewX509Name(cX509Name); - new = X509_NAME_dup(name); - if (!new) - ossl_raise(eX509NameError, "X509_NAME_dup"); + if (!name) { + new = X509_NAME_new(); + } else { + new = X509_NAME_dup(name); + } + if (!new) { + ossl_raise(eX509NameError, NULL); + } SetX509Name(obj, new); return obj; diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 9496c4bf1b49fc..1eff5dd3556d57 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -54,9 +54,14 @@ ossl_x509revoked_new(X509_REVOKED *rev) VALUE obj; obj = NewX509Rev(cX509Rev); - new = X509_REVOKED_dup(rev); - if (!new) - ossl_raise(eX509RevError, "X509_REVOKED_dup"); + if (!rev) { + new = X509_REVOKED_new(); + } else { + new = X509_REVOKED_dup(rev); + } + if (!new) { + ossl_raise(eX509RevError, NULL); + } SetX509Rev(obj, new); return obj; From a9eed306aad6b3733ce6a7b880cd10d12acb8b4b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 28 Jul 2025 00:06:44 +0900 Subject: [PATCH 3/4] Update comments for pack/unpack tests [ci skip] More comprehensive pack/unpack tests are in test_pack.rb. --- test/ruby/test_array.rb | 27 +-------------------------- test/ruby/test_string.rb | 26 +------------------------- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 19f79d236dce46..a3ac0a6a0b420d 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1309,32 +1309,7 @@ def test_pack assert_equal(ary.join(':'), ary2.join(':')) assert_not_nil(x =~ /def/) -=begin - skipping "Not tested: - D,d & double-precision float, native format\\ - E & double-precision float, little-endian byte order\\ - e & single-precision float, little-endian byte order\\ - F,f & single-precision float, native format\\ - G & double-precision float, network (big-endian) byte order\\ - g & single-precision float, network (big-endian) byte order\\ - I & unsigned integer\\ - i & integer\\ - L & unsigned long\\ - l & long\\ - - N & long, network (big-endian) byte order\\ - n & short, network (big-endian) byte-order\\ - P & pointer to a structure (fixed-length string)\\ - p & pointer to a null-terminated string\\ - S & unsigned short\\ - s & short\\ - V & long, little-endian byte order\\ - v & short, little-endian byte order\\ - X & back up a byte\\ - x & null byte\\ - Z & ASCII string (null padded, count is width)\\ -" -=end + # more comprehensive tests are in test_pack.rb end def test_pack_with_buffer diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index e2d0c359cbf38a..8fb57bd58e6111 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2469,31 +2469,7 @@ def test_unpack assert_equal([0xa9, 0x42, 0x2260], S("\xc2\xa9B\xe2\x89\xa0").unpack(S("U*"))) -=begin - skipping "Not tested: - D,d & double-precision float, native format\\ - E & double-precision float, little-endian byte order\\ - e & single-precision float, little-endian byte order\\ - F,f & single-precision float, native format\\ - G & double-precision float, network (big-endian) byte order\\ - g & single-precision float, network (big-endian) byte order\\ - I & unsigned integer\\ - i & integer\\ - L & unsigned long\\ - l & long\\ - m & string encoded in base64 (uuencoded)\\ - N & long, network (big-endian) byte order\\ - n & short, network (big-endian) byte-order\\ - P & pointer to a structure (fixed-length string)\\ - p & pointer to a null-terminated string\\ - S & unsigned short\\ - s & short\\ - V & long, little-endian byte order\\ - v & short, little-endian byte order\\ - X & back up a byte\\ - x & null byte\\ - Z & ASCII string (null padded, count is width)\\" -=end + # more comprehensive tests are in test_pack.rb end def test_upcase From f8e002a6b7228002cc4ccfd1b708a6b4bb2881ba Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 28 Jul 2025 00:17:02 +0900 Subject: [PATCH 4/4] [ruby/English] Exclude unused files from gem https://github.com/ruby/English/commit/6bea25038b --- lib/English.gemspec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/English.gemspec b/lib/English.gemspec index 5f4eb420c23721..261162dde3c676 100644 --- a/lib/English.gemspec +++ b/lib/English.gemspec @@ -15,8 +15,13 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + excludes = %W[ + :^/test :^/spec :^/feature :^/bin + :^/Rakefile :^/Gemfile\* :^/.git* + :^/#{File.basename(__FILE__)} + ] + spec.files = IO.popen(%W[git ls-files -z --] + excludes, err: IO::NULL) do |f| + f.readlines("\x0", chomp: true) end spec.require_paths = ["lib"] end