Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions mrbgems/mruby-regexp/mrblib/string_regexp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,10 @@ def split(pattern = nil, *args)
# `ary[obj]` and `"s" * obj` all reject an object that only defines
# `to_int`; dispatching it here would leave this the one place in the tree
# that accepts one, as the same reasoning keeps `match` off `to_str`.
# `is_a?` is redefinable, so a limit claiming to be an Integer would skip
# that conversion and reach the arithmetic below as itself. `Module#===`
# reads the real type and cannot be redefined.
if limit_given && !(Integer === limit)
limit = Integer.__ensure(limit)
end
# Every limit goes through it, an Integer included: a Bigint is an Integer
# and does not fit `mrb_int`, and `__ensure` is what narrows it and raises
# the `RangeError` `__split` raises on the string path.
limit = Integer.__ensure(limit) if limit_given
# `nil?` and `is_a?` are redefinable, so an argument answering either one
# could steer itself around the check below and reach `__split` instead.
# `Module#===` reads the real type and cannot be redefined.
Expand Down
16 changes: 16 additions & 0 deletions mrbgems/mruby-regexp/test/regexp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,22 @@ def -(other)
assert_raise(TypeError) { "a,b,c".split(/,/, StringSplitLimitComparable.new) }
end

assert("String#split with a Bigint limit") do
# A Bigint is an Integer, so a check on the class let one through unconverted
# and the split loop ran with a limit that does not fit `mrb_int`, while the
# String pattern raised in `__split`. The exponent is a variable because a
# constant power out of `mrb_int` range fails the build rather than raising.
exp = 70
begin
limit = 2 ** exp
rescue RangeError
skip "requires mruby-bigint"
end
assert_raise(RangeError) { "a,b,c".split(/,/, limit) }
assert_raise(RangeError) { "a,b,c".split(",", limit) }
assert_raise(RangeError) { "a,b,c".split(/,/, -limit) }
end

assert("String#split with empty regexp") do
assert_equal ["a", "b", "c"], "abc".split(//)
assert_equal ["a", "bc"], "abc".split(//, 2)
Expand Down
Loading