From e7d187511cd4b6237fc5c2a6bc61814d3e98070f Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Mon, 14 Sep 2020 01:47:47 +0800 Subject: [PATCH 1/2] add offset overflow check --- src/OffsetArrays.jl | 10 ++++++++++ test/runtests.jl | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 195697f3..241f4190 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -15,10 +15,20 @@ include("axes.jl") struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N} parent::AA offsets::NTuple{N,Int} + function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}) where {T, N, AA<:AbstractArray} + overflow_check.(axes(parent), offsets) + new{T, N, AA}(parent, offsets) + end end OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA} OffsetMatrix{T,AA<:AbstractArray} = OffsetArray{T,2,AA} +function overflow_check(r, offset::T) where T + throw_offseterror() = throw(ArgumentError("Boundary overflow detected: offset $offset should be smaller than $(typemax(T) - last(r))")) + if offset > 0 && last(r) > typemax(T) - offset + throw_offseterror() + end +end ## OffsetArray constructors offset(axparent::AbstractUnitRange, ax::AbstractUnitRange) = first(ax) - first(axparent) diff --git a/test/runtests.jl b/test/runtests.jl index d1cec2e2..4d86fc7d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ using OffsetArrays using OffsetArrays: IdentityUnitRange, no_offset_view +using OffsetArrays: IdOffsetRange using Test, Aqua using LinearAlgebra using DelimitedFiles @@ -125,6 +126,9 @@ end w = zeros(5:6) @test OffsetVector(w, :) == OffsetArray(w, (:,)) == OffsetArray(w, :) == OffsetArray(w, axes(w)) @test axes(OffsetVector(w, :)) == axes(w) + + @test axes(OffsetVector(v, typemax(Int)-length(v))) == (IdOffsetRange(axes(v)[1], typemax(Int)-length(v)), ) + @test_throws ArgumentError OffsetVector(v, typemax(Int)-length(v)+1) end @testset "OffsetMatrix constructors" begin @@ -158,6 +162,10 @@ end @test axes(OffsetMatrix(w, :, CartesianIndices((0:1,)))) == (3:4, 0:1) @test axes(OffsetMatrix(w, CartesianIndices((0:1,)), :)) == (0:1, 5:6) + + @test axes(OffsetMatrix(v, typemax(Int)-size(v, 1), 0)) == (IdOffsetRange(axes(v)[1], typemax(Int)-size(v, 1)), axes(v, 2)) + @test_throws ArgumentError OffsetMatrix(v, typemax(Int)-size(v,1)+1, 0) + @test_throws ArgumentError OffsetMatrix(v, 0, typemax(Int)-size(v, 2)+1) end @testset "construct OffsetArray with CartesianIndices" begin From 967873f196b722d86e97f7a1f2efed1be5d9ab77 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Mon, 14 Sep 2020 03:14:29 +0800 Subject: [PATCH 2/2] also check negative cases --- src/OffsetArrays.jl | 5 +++-- test/runtests.jl | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 241f4190..d8a7bae7 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -24,9 +24,10 @@ OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA} OffsetMatrix{T,AA<:AbstractArray} = OffsetArray{T,2,AA} function overflow_check(r, offset::T) where T - throw_offseterror() = throw(ArgumentError("Boundary overflow detected: offset $offset should be smaller than $(typemax(T) - last(r))")) if offset > 0 && last(r) > typemax(T) - offset - throw_offseterror() + throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or less than $(typemax(T) - last(r))")) + elseif offset < 0 && first(r) < typemin(T) - offset + throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or greater than $(typemin(T) - first(r))")) end end ## OffsetArray constructors diff --git a/test/runtests.jl b/test/runtests.jl index 4d86fc7d..da604adb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -129,6 +129,10 @@ end @test axes(OffsetVector(v, typemax(Int)-length(v))) == (IdOffsetRange(axes(v)[1], typemax(Int)-length(v)), ) @test_throws ArgumentError OffsetVector(v, typemax(Int)-length(v)+1) + ao = OffsetArray(v, typemin(Int)) + @test_nowarn OffsetArray{Float64, 1, typeof(ao)}(ao, (-1, )) + @test_throws ArgumentError OffsetArray{Float64, 1, typeof(ao)}(ao, (-2, )) # inner Constructor + @test_throws ArgumentError OffsetArray(ao, (-2, )) # convinient constructor accumulate offsets end @testset "OffsetMatrix constructors" begin