From c500caa3eef30be5b3d16c65e0a3ff22df7b744a Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Tue, 26 Jun 2018 13:41:20 +0300 Subject: [PATCH] Fix conversion in getindex (#26615) * Test more out of bounds errors for the UnitRange type * Do the conversion in getindex of UnitRange only when returning --- base/range.jl | 18 +++++++++++++++--- test/ranges.jl | 6 ++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/base/range.jl b/base/range.jl index 748f8104bd9e1..1aaa5c64235f8 100644 --- a/base/range.jl +++ b/base/range.jl @@ -478,11 +478,23 @@ end ## indexing +_in_unit_range(v::UnitRange, val, i::Integer) = i > 0 && val <= v.stop && val >= v.start + function getindex(v::UnitRange{T}, i::Integer) where T @_inline_meta - ret = convert(T, first(v) + i - 1) - @boundscheck ((i > 0) & (ret <= v.stop) & (ret >= v.start)) || throw_boundserror(v, i) - ret + val = convert(T, v.start + i - 1) + @boundscheck _in_unit_range(v, val, i) || throw_boundserror(v, i) + val +end + +const OverflowSafe = Union{Bool,Int8,Int16,Int32,Int64,Int128, + UInt8,UInt16,UInt32,UInt64,UInt128} + +function getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe} + @_inline_meta + val = v.start + i - 1 + @boundscheck _in_unit_range(v, val, i) || throw_boundserror(v, i) + val % T end function getindex(v::OneTo{T}, i::Integer) where T diff --git a/test/ranges.jl b/test/ranges.jl index d3575bde6d736..aa0d7980de956 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1286,6 +1286,12 @@ end @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} end +@testset "Issue #26608" begin + @test_throws BoundsError (Int8(-100):Int8(100))[400] + @test_throws BoundsError (-100:100)[typemax(UInt)] + @test_throws BoundsError (false:true)[3] +end + module NonStandardIntegerRangeTest using Test