diff --git a/ChangeLog b/ChangeLog index ce4c97ebed..44a28881bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Wed Jan 30 15:00:05 2013 Marc-Andre Lafortune + + * array.c (rb_ary_bsearch): Raise TypeError on bad return from block + + * range.c (range_bsearch): ditto + + * test/ruby/test_array.rb (class): Test for above + + * test/ruby/test_range.rb (class): ditto + Wed Jan 30 14:46:28 2013 Marc-Andre Lafortune * range.c: Restrict bsearch to integers [#7728] diff --git a/array.c b/array.c index 3f448063ce..e76801df50 100644 --- a/array.c +++ b/array.c @@ -2462,7 +2462,9 @@ rb_ary_bsearch(VALUE ary) } } else { - smaller = RTEST(v); + rb_raise(rb_eTypeError, "wrong argument type %s" + "(must respond be numeric, true, false or nil)", + rb_obj_classname(v)); } if (smaller) { high = mid; diff --git a/range.c b/range.c index 394495146b..388418bff7 100644 --- a/range.c +++ b/range.c @@ -595,7 +595,9 @@ range_bsearch(VALUE range) smaller = cmp < 0; \ } \ else { \ - smaller = RTEST(v); \ + rb_raise(rb_eTypeError, "wrong argument type %s" \ + "(must respond be numeric, true, false or nil)", \ + rb_obj_classname(v)); \ } \ } while (0) diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index ae0f76c970..3ab0895f8c 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -2249,6 +2249,13 @@ class TestArray < Test::Unit::TestCase assert_raise(ArgumentError) { a.rotate!(1, 1) } end + def test_bsearch_typechecks_return_values + assert_raise(TypeError) do + [1, 2, 42, 100, 666].bsearch{ "not ok" } + end + assert_equal [1, 2, 42, 100, 666].bsearch{}, [1, 2, 42, 100, 666].bsearch{false} + end + def test_bsearch_with_no_block enum = [1, 2, 42, 100, 666].bsearch assert_nil enum.size @@ -2276,9 +2283,4 @@ class TestArray < Test::Unit::TestCase assert_include([4, 7], a.bsearch {|x| (2**100).coerce((1 - x / 4) * (2**100)).first }) end - - def test_bsearch_undefined - a = [0, 4, 7, 10, 12] - assert_equal(nil, a.bsearch {|x| "foo" }) # undefined behavior - end end diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index d859969ded..1f370cfaee 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -357,6 +357,13 @@ class TestRange < Test::Unit::TestCase assert_equal 42, (1..42).each.size end + def test_bsearch_typechecks_return_values + assert_raise(TypeError) do + (1..42).bsearch{ "not ok" } + end + assert_equal (1..42).bsearch{}, (1..42).bsearch{false} + end + def test_bsearch_with_no_block enum = (42...666).bsearch assert_nil enum.size