diff --git a/set.c b/set.c index 55d0e62633..61f1fd8bc4 100644 --- a/set.c +++ b/set.c @@ -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); diff --git a/test/ruby/test_set.rb b/test/ruby/test_set.rb index 87e1fd8d26..934a470c1e 100644 --- a/test/ruby/test_set.rb +++ b/test/ruby/test_set.rb @@ -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