From ab11395ad163dfa34178edce1021ecf7a6123ffe Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Thu, 11 Jun 2020 14:13:54 +0200 Subject: [PATCH 1/2] deleteat! : check bounds for the first passed index All other indices are bound-checked. Currently, the behavior looks like: ```julia julia> deleteat!([1:1000;], [-100]) signal (11): Segmentation fault [...] julia> deleteat!(BigInt[0], [0]) free(): invalid next size (normal) signal (6): Aborted [...] julia> deleteat!(BigInt[0], [-100]) ERROR: UndefRefError: access to undefined reference [...] julia> deleteat!([0], [0]) Int64[] julia> deleteat!([0], [2]) 1-element Array{Int64,1}: 0 julia> deleteat!([0], [3]) ERROR: InexactError: check_top_bit(UInt64, -1) [...] ``` With this commit, all these expressions throw a `BoundsError`. --- base/array.jl | 4 ++-- test/arrayops.jl | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/base/array.jl b/base/array.jl index 8954f3e5b9d23..c0a1ec96fb12f 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1352,9 +1352,9 @@ function _deleteat!(a::Vector, inds, dltd=Nowhere()) n = length(a) y = iterate(inds) y === nothing && return a - n == 0 && throw(BoundsError(a, inds)) (p, s) = y - p <= n && push!(dltd, @inbounds a[p]) + 1 <= p <= n || throw(BoundsError(a, p)) + push!(dltd, @inbounds a[p]) q = p+1 while true y = iterate(inds, s) diff --git a/test/arrayops.jl b/test/arrayops.jl index 9ecd9f4a0bab2..e8acde4c8826e 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1446,11 +1446,15 @@ end @test deleteat!(a, [1,3,5,7:10...]) == [2,4,6] @test_throws BoundsError deleteat!(a, 13) @test_throws BoundsError deleteat!(a, [1,13]) - @test_throws ArgumentError deleteat!(a, [5,3]) + @test_throws ArgumentError deleteat!(a, [3,2]) # not sorted @test_throws BoundsError deleteat!(a, 5:20) @test_throws BoundsError deleteat!(a, Bool[]) @test_throws BoundsError deleteat!(a, [true]) @test_throws BoundsError deleteat!(a, falses(11)) + @test_throws BoundsError deleteat!(a, [0]) + @test_throws BoundsError deleteat!(a, [4]) + @test_throws BoundsError deleteat!(a, [5]) + @test_throws BoundsError deleteat!(a, [5, 3]) @test_throws BoundsError deleteat!([], 1) @test_throws BoundsError deleteat!([], [1]) From 9a0c498eefa0f31cf021f48d0b3afddb282dc6cd Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Tue, 16 Jun 2020 09:47:38 +0200 Subject: [PATCH 2/2] Update base/array.jl Co-authored-by: Simeon Schaub --- base/array.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/array.jl b/base/array.jl index c0a1ec96fb12f..bd6807853c93e 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1353,7 +1353,7 @@ function _deleteat!(a::Vector, inds, dltd=Nowhere()) y = iterate(inds) y === nothing && return a (p, s) = y - 1 <= p <= n || throw(BoundsError(a, p)) + checkbounds(a, p) push!(dltd, @inbounds a[p]) q = p+1 while true