diff --git a/NEWS.md b/NEWS.md index 59a2b4b49d4c44..9712152da6a7b9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -32,6 +32,15 @@ releases. ### The following bundled gems are updated. +* minitest 6.0.1 +* test-unit 3.7.6 +* rss 0.3.2 +* net-imap 0.6.2 +* typeprof 0.31.1 +* debug 1.11.1 +* mutex_m 0.3.0 +* rdoc 7.0.3 + ### RubyGems and Bundler Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for details. diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index db65e99888d3bf..f3cd247c8fdfbc 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -401,9 +401,9 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) } out_len = in_len + EVP_MAX_BLOCK_LENGTH; - if (NIL_P(str)) { - str = rb_str_new(0, out_len); - } else { + if (NIL_P(str)) + str = rb_str_buf_new(out_len); + else { StringValue(str); if ((long)rb_str_capacity(str) >= out_len) rb_str_modify(str); @@ -411,9 +411,9 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) rb_str_modify_expand(str, out_len - RSTRING_LEN(str)); } - if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) - ossl_raise(eCipherError, NULL); - assert(out_len <= RSTRING_LEN(str)); + if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), + &out_len, in, in_len)) + ossl_raise(eCipherError, "EVP_CipherUpdate"); rb_str_set_len(str, out_len); return str; @@ -456,7 +456,6 @@ ossl_cipher_final(VALUE self) ossl_raise(eCipherError, "cipher final failed"); } } - assert(out_len <= RSTRING_LEN(str)); rb_str_set_len(str, out_len); return str; diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index e952b7871b3f6f..758d37293ffc2c 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -258,6 +258,22 @@ is_specified_ip_address(const char *hostname) inet_pton(AF_INET, hostname, &ipv4addr) == 1); } +static int +is_local_port_fixed(const char *portp) +{ + if (!portp) return 0; + + char *endp; + errno = 0; + long port = strtol(portp, &endp, 10); + + if (endp == portp) return 0; + if (errno == ERANGE) return 0; + if (port <= 0) return 0; + + return port != 0; +} + struct fast_fallback_inetsock_arg { VALUE self; @@ -1314,13 +1330,15 @@ rsock_init_inetsock( if (type == INET_CLIENT && FAST_FALLBACK_INIT_INETSOCK_IMPL == 1 && RTEST(fast_fallback)) { struct rb_addrinfo *local_res = NULL; - char *hostp, *portp; - char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + char *hostp, *portp, *local_portp; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV], local_pbuf[NI_MAXSERV]; int additional_flags = 0; + int local_flags = 0; hostp = raddrinfo_host_str(remote_host, hbuf, sizeof(hbuf), &additional_flags); portp = raddrinfo_port_str(remote_serv, pbuf, sizeof(pbuf), &additional_flags); + local_portp = raddrinfo_port_str(local_serv, local_pbuf, sizeof(local_pbuf), &local_flags); - if (!is_specified_ip_address(hostp)) { + if (!is_specified_ip_address(hostp) && !is_local_port_fixed(local_portp)) { int target_families[2] = { 0, 0 }; int resolving_family_size = 0; diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index e74eaec43a3318..36fcceaee96300 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -660,12 +660,11 @@ def accept_nonblock(exception: true) # puts sock.read # } def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil, open_timeout: nil, fast_fallback: tcp_fast_fallback, &) # :yield: socket - if open_timeout && (connect_timeout || resolv_timeout) raise ArgumentError, "Cannot specify open_timeout along with connect_timeout or resolv_timeout" end - sock = if fast_fallback && !(host && ip_address?(host)) + sock = if fast_fallback && !(host && ip_address?(host)) && !(local_port && local_port.to_i != 0) tcp_with_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, open_timeout:) else tcp_without_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, open_timeout:) @@ -736,7 +735,7 @@ def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil, if local_addrinfos.any? local_addrinfo = local_addrinfos.find { |lai| lai.afamily == addrinfo.afamily } - if local_addrinfo.nil? # Connecting addrinfoと同じアドレスファミリのLocal addrinfoがない + if local_addrinfo.nil? if resolution_store.any_addrinfos? # Try other Addrinfo in next "while" next diff --git a/gems/bundled_gems b/gems/bundled_gems index 9461122e62dd73..f4afd8e9c27ac9 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -6,10 +6,10 @@ # - revision: revision in repository-url to test # if `revision` is not given, "v"+`version` or `version` will be used. -minitest 6.0.0 https://github.com/minitest/minitest +minitest 6.0.1 https://github.com/minitest/minitest power_assert 3.0.1 https://github.com/ruby/power_assert rake 13.3.1 https://github.com/ruby/rake -test-unit 3.7.5 https://github.com/test-unit/test-unit +test-unit 3.7.6 https://github.com/test-unit/test-unit rexml 3.4.4 https://github.com/ruby/rexml rss 0.3.2 https://github.com/ruby/rss net-ftp 0.3.9 https://github.com/ruby/net-ftp diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb index 93766cfc88ce17..5b867671d312ad 100644 --- a/test/openssl/test_cipher.rb +++ b/test/openssl/test_cipher.rb @@ -134,13 +134,14 @@ def test_ctr_if_exists def test_update_with_buffer cipher = OpenSSL::Cipher.new("aes-128-ecb").encrypt cipher.random_key - expected = cipher.update("data") << cipher.final - assert_equal 16, expected.bytesize + expected = cipher.update("data" * 10) << cipher.final + assert_equal 48, expected.bytesize # Buffer is supplied cipher.reset buf = String.new - assert_same buf, cipher.update("data", buf) + assert_same buf, cipher.update("data" * 10, buf) + assert_equal 32, buf.bytesize assert_equal expected, buf + cipher.final # Buffer is frozen @@ -149,9 +150,9 @@ def test_update_with_buffer # Buffer is a shared string [ruby-core:120141] [Bug #20937] cipher.reset - buf = "x" * 1024 - shared = buf[-("data".bytesize + 32)..-1] - assert_same shared, cipher.update("data", shared) + buf = "x".b * 1024 + shared = buf[-("data".bytesize * 10 + 32)..-1] + assert_same shared, cipher.update("data" * 10, shared) assert_equal expected, shared + cipher.final end