Skip to content

Commit 77988ea

Browse files
committed
overflow check in summing offsets
1 parent 5baab27 commit 77988ea

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/OffsetArrays.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ Type alias and convenience constructor for two-dimensional [`OffsetArray`](@ref)
135135
"""
136136
const OffsetMatrix{T,AA<:AbstractMatrix{T}} = OffsetArray{T,2,AA}
137137

138-
function overflow_check(r, offset::T) where T
138+
# checks if the offset may be added to the range without overflowing
139+
function overflow_check(r::AbstractUnitRange{T}, offset::T) where T<:Integer
139140
# This gives some performance boost https://github.com/JuliaLang/julia/issues/33273
140141
throw_upper_overflow_error(val) = throw(OverflowError("offset should be <= $(typemax(T) - val) corresponding to the axis $r, received an offset $offset"))
141142
throw_lower_overflow_error(val) = throw(OverflowError("offset should be >= $(typemin(T) - val) corresponding to the axis $r, received an offset $offset"))
@@ -149,6 +150,19 @@ function overflow_check(r, offset::T) where T
149150
elseif offset < 0 && firstlast_min < typemin(T) - offset
150151
throw_lower_overflow_error(firstlast_min)
151152
end
153+
return nothing
154+
end
155+
# checks if the two offsets may be added together without overflowing
156+
function overflow_check(offset1::T, offset2::T) where {T<:Integer}
157+
throw_upper_overflow_error() = throw(OverflowError("offset should be <= $(typemax(eltype(offset1)) - offset1) given a pre-existing offset of $offset1, received an offset $offset2"))
158+
throw_lower_overflow_error() = throw(OverflowError("offset should be >= $(typemin(eltype(offset1)) - offset1) given a pre-existing offset of $offset1, received an offset $offset2"))
159+
160+
if offset1 > 0 && offset2 > typemax(T) - offset1
161+
throw_upper_overflow_error()
162+
elseif offset1 < 0 && offset2 < typemin(T) - offset1
163+
throw_lower_overflow_error()
164+
end
165+
return nothing
152166
end
153167

154168
# Tuples of integers are treated as offsets
@@ -177,7 +191,8 @@ for FT in (:OffsetArray, :OffsetVector, :OffsetMatrix)
177191
# empty tuples are handled here
178192
@eval @inline function $FT(A::OffsetArray, offsets::Tuple{Vararg{Int}})
179193
_checkindices(A, offsets, "offsets")
180-
foreach(overflow_check, axes(A), offsets)
194+
# ensure that the offsets may be added together without an overflow
195+
foreach(overflow_check, A.offsets, offsets)
181196
$FT(parent(A), map(+, A.offsets, offsets))
182197
end
183198
@eval @inline function $FT(A::OffsetArray, offsets::Tuple{Integer,Vararg{Integer}})

0 commit comments

Comments
 (0)