[Bug #21513] Raise on converting endless range to set

ref: https://bugs.ruby-lang.org/issues/21513

Before this patch, trying to convert endless range (e.g. `(1..)`) to set
(using `to_set`) would hang
This commit is contained in:
viralpraxis 2025-07-16 01:59:22 +04:00 committed by Akinori Musha
parent d9a14c299f
commit d4020dd5fa
2 changed files with 22 additions and 0 deletions

8
set.c
View file

@ -505,6 +505,14 @@ set_i_initialize(int argc, VALUE *argv, VALUE set)
}
}
else {
ID id_size = rb_intern("size");
if (rb_obj_is_kind_of(other, rb_mEnumerable) && rb_respond_to(other, id_size)) {
VALUE size = rb_funcall(other, id_size, 0);
if (RB_TYPE_P(size, T_FLOAT) && RFLOAT_VALUE(size) == INFINITY) {
rb_raise(rb_eArgError, "cannot initialize Set from an object with infinite size");
}
}
rb_block_call(other, enum_method_id(other), 0, 0,
rb_block_given_p() ? set_initialize_with_block : set_initialize_without_block,
set);

View file

@ -81,6 +81,20 @@ class TC_Set < Test::Unit::TestCase
s = Set.new(ary) { |o| o * 2 }
assert_equal([2,4,6], s.sort)
assert_raise(ArgumentError) {
Set.new((1..))
}
assert_raise(ArgumentError) {
Set.new((1..), &:succ)
}
assert_raise(ArgumentError) {
Set.new(1.upto(Float::INFINITY))
}
assert_raise(ArgumentError) {
Set.new(Object.new)
}
end
def test_clone