diff --git a/base/strings/basic.jl b/base/strings/basic.jl index 85a4dacbd323c..1d563890998fe 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -105,7 +105,7 @@ UInt8 See also [`ncodeunits`](@ref), [`checkbounds`](@ref). """ @propagate_inbounds codeunit(s::AbstractString, i::Integer) = i isa Int ? - throw(MethodError(codeunit, (s, i))) : codeunit(s, Int(i)) + throw(MethodError(codeunit, (s, i))) : codeunit(s, Int(i)::Int) """ isvalid(s::AbstractString, i::Integer)::Bool @@ -141,7 +141,7 @@ Stacktrace: ``` """ @propagate_inbounds isvalid(s::AbstractString, i::Integer) = i isa Int ? - throw(MethodError(isvalid, (s, i))) : isvalid(s, Int(i)) + throw(MethodError(isvalid, (s, i))) : isvalid(s, Int(i)::Int) """ iterate(s::AbstractString, i::Integer)::Union{Tuple{<:AbstractChar, Int}, Nothing} @@ -154,7 +154,7 @@ of the iteration protocol may assume that `i` is the start of a character in `s` See also [`getindex`](@ref), [`checkbounds`](@ref). """ @propagate_inbounds iterate(s::AbstractString, i::Integer) = i isa Int ? - throw(MethodError(iterate, (s, i))) : iterate(s, Int(i)) + throw(MethodError(iterate, (s, i))) : iterate(s, Int(i)::Int) ## basic generic definitions ## diff --git a/test/faulty_constructor_method_should_not_cause_stack_overflows.jl b/test/faulty_constructor_method_should_not_cause_stack_overflows.jl index 8dede73e2ae7a..08c9c1d1e3b09 100644 --- a/test/faulty_constructor_method_should_not_cause_stack_overflows.jl +++ b/test/faulty_constructor_method_should_not_cause_stack_overflows.jl @@ -1,3 +1,4 @@ +# new types with invalid constructors for (typ, sup) in ( (:Char, :AbstractChar), (:String, :AbstractString), @@ -9,6 +10,18 @@ for (typ, sup) in ( @eval function Base.$typ(x::$fau) x end end +# valid new subtype of `AbstractString` +struct MyString <: AbstractString + str::String +end +Base.lastindex(s::MyString) = lastindex(s.str) +Base.iterate(s::MyString) = iterate(s, 1) +Base.iterate(s::MyString, state) = iterate(s, Int(state)::Int) +Base.iterate(s::MyString, state::Integer) = iterate(s, Int(state)::Int) +Base.iterate(s::MyString, state::Int) = iterate(s.str, state) +Base.isequal(a::MyString, b::MyString) = isequal(a.str, b.str) +Base.:(==)(a::MyString, b::MyString) = (a.str == b.str) + using Test using Unicode: Unicode @@ -39,14 +52,18 @@ using Unicode: Unicode end @testset let x = FaultyInt() @test_throws exc readbytes!(IOBuffer(), Vector{UInt8}(undef, 0), x) - @test_throws exc length("", x, x) - @test_throws exc thisind("", x) - @test_throws exc prevind("", x) - @test_throws exc prevind("", x, x) - @test_throws exc nextind("", x) - @test_throws exc nextind("", x, x) - @test_throws exc codeunit("", x) - @test_throws exc SubString("", x, x) + for s in ("", MyString("")) + @test_throws exc iterate(s, x) + @test_throws exc isvalid(s, x) + @test_throws exc length(s, x, x) + @test_throws exc thisind(s, x) + @test_throws exc prevind(s, x) + @test_throws exc prevind(s, x, x) + @test_throws exc nextind(s, x) + @test_throws exc nextind(s, x, x) + @test_throws exc codeunit(s, x) + @test_throws exc SubString(s, x, x) + end end @testset let x = FaultyUInt32() @test_throws exc Char(x)