Skip to content

Commit

Permalink
Array: fix some bugs in #fill. Fixes #4539
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Jun 10, 2017
1 parent b4e209b commit 4a9b867
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
12 changes: 12 additions & 0 deletions spec/std/array_spec.cr
Expand Up @@ -561,12 +561,24 @@ describe "Array" do
a.fill('x', -2).should eq(expected)
end

it "raises when given big negative number (#4539)" do
expect_raises(IndexError) do
['a', 'b', 'c'].fill('x', -4)
end
end

it "replaces only values between negative index and size" do
a = ['a', 'b', 'c']
expected = ['a', 'b', 'x']
a.fill('x', -1, 1).should eq(expected)
end

it "raises when given big negative number in from/count (#4539)" do
expect_raises(IndexError) do
['a', 'b', 'c'].fill('x', -4, 1)
end
end

it "replaces only values in range" do
a = ['a', 'b', 'c']
expected = ['x', 'x', 'c']
Expand Down
17 changes: 10 additions & 7 deletions src/array.cr
Expand Up @@ -706,14 +706,16 @@ class Array(T)
#
# Negative values of *from* count from the end of the array.
#
# Raises `IndexError` if *from* is outside the array range.
#
# ```
# a = [1, 2, 3, 4]
# a.fill(2) { |i| i * i } # => [1, 2, 4, 9]
# ```
def fill(from : Int)
from += size if from < 0

raise IndexError.new if from >= size
raise IndexError.new unless 0 <= from < size

from.upto(size - 1) { |i| @buffer[i] = yield i }

Expand All @@ -725,21 +727,22 @@ class Array(T)
#
# Negative values of *from* count from the end of the array.
#
# Raises `IndexError` if *from* is outside the array range.
#
# Has no effect if *count* is zero or negative.
#
# ```
# a = [1, 2, 3, 4, 5, 6]
# a.fill(2, 2) { |i| i * i } # => [1, 2, 4, 9, 5, 6]
# ```
def fill(from : Int, count : Int)
return self if count < 0
return self if count <= 0

from += size if from < 0
count += size if count < 0

raise IndexError.new if from >= size || count + from > size

count += from - 1
raise IndexError.new unless 0 <= from < size && from + count <= size

from.upto(count) { |i| @buffer[i] = yield i }
from.upto(from + count - 1) { |i| @buffer[i] = yield i }

self
end
Expand Down

0 comments on commit 4a9b867

Please sign in to comment.