Fix: Do not pass negative timeout to Addrinfo#connect_internal (#15578)

This change fixes a bug where, with `Socket.tcp`’s `fast_fallback option` disabled, specifying `open_timeout` could unintentionally pass a negative value to `Addrinfo#connect_internal`, `causing an ArgumentError`.

```
❯ ruby -rsocket -e 'p Socket.tcp("localhost", 9292, open_timeout: 1, fast_fallback: false)'
/Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'IO#wait_writable': time interval must not be negative (ArgumentError)

          sock.wait_writable(timeout) or
                             ^^^^^^^
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:64:in 'Addrinfo#connect_internal'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:141:in 'Addrinfo#connect'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:964:in 'block in Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Array#each'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:231:in 'Addrinfo.foreach'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:945:in 'Socket.tcp_without_fast_fallback'
	from /Users/misaki-shioi/src/install/lib/ruby/4.0.0+0/socket.rb:671:in 'Socket.tcp'
	from -e:1:in '<main>'
```
This commit is contained in:
Misaki Shioi 2025-12-16 19:52:45 +09:00 committed by GitHub
parent e42bcd7ce7
commit 2b1a9afbfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2025-12-16 10:53:16 +00:00
Merged-By: shioimm <shioi.mm@gmail.com>

View File

@ -948,7 +948,14 @@ class Socket < BasicSocket
local_addr = nil
end
begin
timeout = open_timeout ? open_timeout - (current_clock_time - starts_at) : connect_timeout
timeout =
if open_timeout
t = open_timeout - (current_clock_time - starts_at)
t.negative? ? 0 : t
else
connect_timeout
end
sock = local_addr ?
ai.connect_from(local_addr, timeout:) :
ai.connect(timeout:)