diff --git a/spec/core/io/select_spec.rb b/spec/core/io/select_spec.rb index 9fdb7e12c9..8e0b89c053 100644 --- a/spec/core/io/select_spec.rb +++ b/spec/core/io/select_spec.rb @@ -112,7 +112,17 @@ end it "raises an ArgumentError when passed a negative timeout" do - -> { IO.select(nil, nil, nil, -5)}.should raise_error(ArgumentError) + -> { IO.select(nil, nil, nil, -5)}.should raise_error(ArgumentError, "time interval must not be negative") + end + + ruby_version_is "4.0" do + it "raises an ArgumentError when passed negative infinity as timeout" do + -> { IO.select(nil, nil, nil, -Float::INFINITY)}.should raise_error(ArgumentError, "time interval must not be negative") + end + end + + it "raises an RangeError when passed NaN as timeout" do + -> { IO.select(nil, nil, nil, Float::NAN)}.should raise_error(RangeError, "NaN out of Time range") end describe "returns the available descriptors when the file descriptor" do diff --git a/src/io_object.cpp b/src/io_object.cpp index 5c8229b0bb..5b4ee17f52 100644 --- a/src/io_object.cpp +++ b/src/io_object.cpp @@ -1107,6 +1107,8 @@ Value IoObject::select(Env *env, Value read_ios, Optional write_ios, Opti timeval timeout_tv = { 0, 0 }, *timeout_ptr = nullptr; if (timeout && !timeout->is_nil() && !(timeout->is_float() && timeout->as_float()->is_positive_infinity())) { + if (timeout->is_float() && timeout->as_float()->is_nan()) + env->raise("RangeError", "NaN out of Time range"); const auto timeout_f = timeout->to_f(env)->to_double(); if (timeout_f < 0) env->raise("ArgumentError", "time interval must not be negative");