Skip to content

Commit ce6298c

Browse files
authored
add offset overflow check (#144)
* add offset overflow check * also check negative cases
1 parent 1d294f8 commit ce6298c

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

src/OffsetArrays.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,21 @@ include("axes.jl")
1515
struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N}
1616
parent::AA
1717
offsets::NTuple{N,Int}
18+
function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}) where {T, N, AA<:AbstractArray}
19+
overflow_check.(axes(parent), offsets)
20+
new{T, N, AA}(parent, offsets)
21+
end
1822
end
1923
OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA}
2024
OffsetMatrix{T,AA<:AbstractArray} = OffsetArray{T,2,AA}
2125

26+
function overflow_check(r, offset::T) where T
27+
if offset > 0 && last(r) > typemax(T) - offset
28+
throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or less than $(typemax(T) - last(r))"))
29+
elseif offset < 0 && first(r) < typemin(T) - offset
30+
throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or greater than $(typemin(T) - first(r))"))
31+
end
32+
end
2233
## OffsetArray constructors
2334

2435
offset(axparent::AbstractUnitRange, ax::AbstractUnitRange) = first(ax) - first(axparent)

test/runtests.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using OffsetArrays
22
using OffsetArrays: IdentityUnitRange, no_offset_view
3+
using OffsetArrays: IdOffsetRange
34
using Test, Aqua
45
using LinearAlgebra
56
using DelimitedFiles
@@ -125,6 +126,13 @@ end
125126
w = zeros(5:6)
126127
@test OffsetVector(w, :) == OffsetArray(w, (:,)) == OffsetArray(w, :) == OffsetArray(w, axes(w))
127128
@test axes(OffsetVector(w, :)) == axes(w)
129+
130+
@test axes(OffsetVector(v, typemax(Int)-length(v))) == (IdOffsetRange(axes(v)[1], typemax(Int)-length(v)), )
131+
@test_throws ArgumentError OffsetVector(v, typemax(Int)-length(v)+1)
132+
ao = OffsetArray(v, typemin(Int))
133+
@test_nowarn OffsetArray{Float64, 1, typeof(ao)}(ao, (-1, ))
134+
@test_throws ArgumentError OffsetArray{Float64, 1, typeof(ao)}(ao, (-2, )) # inner Constructor
135+
@test_throws ArgumentError OffsetArray(ao, (-2, )) # convinient constructor accumulate offsets
128136
end
129137

130138
@testset "OffsetMatrix constructors" begin
@@ -158,6 +166,10 @@ end
158166

159167
@test axes(OffsetMatrix(w, :, CartesianIndices((0:1,)))) == (3:4, 0:1)
160168
@test axes(OffsetMatrix(w, CartesianIndices((0:1,)), :)) == (0:1, 5:6)
169+
170+
@test axes(OffsetMatrix(v, typemax(Int)-size(v, 1), 0)) == (IdOffsetRange(axes(v)[1], typemax(Int)-size(v, 1)), axes(v, 2))
171+
@test_throws ArgumentError OffsetMatrix(v, typemax(Int)-size(v,1)+1, 0)
172+
@test_throws ArgumentError OffsetMatrix(v, 0, typemax(Int)-size(v, 2)+1)
161173
end
162174

163175
@testset "construct OffsetArray with CartesianIndices" begin

0 commit comments

Comments
 (0)