summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--array.c4
-rw-r--r--range.c4
-rw-r--r--test/ruby/test_array.rb12
-rw-r--r--test/ruby/test_range.rb7
5 files changed, 30 insertions, 7 deletions
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 <ruby-core@marc-andre.ca>
+
+ * 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 <ruby-core@marc-andre.ca>
* 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