Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #29451: parse(Int, s::AbstractString) when ncodeunits(s) > lastindex(s) #29465

Merged
merged 2 commits into from
Oct 3, 2018

Conversation

samoconnor
Copy link
Contributor

#29451 :

i <= ncodeunits(s) should be i <= endpos ?

julia/base/parse.jl

Lines 75 to 76 in 1a1d6b6

if c == '0' && i <= ncodeunits(s)
c, i = iterate(s,i)::Tuple{Char, Int}

When I do parse(Int, "0") where "0" is an AbstractString and ncodeunits > lastindex, i get this:
TypeError: in parseint_preamble, in typeassert, expected Tuple{Char,Int64}, got Nothing

Bug introduced here ? 1a1d6b6#r30713661

Needs a sanity check from someone who knows the detail of the parser code @Keno? @StefanKarpinski?

Needs a sanity check from someone who knows the detail of the parser code @Keno? @StefanKarpinski?
@KristofferC KristofferC added the needs tests Unit tests are required for this change label Oct 2, 2018
@samoconnor
Copy link
Contributor Author

samoconnor commented Oct 2, 2018

@KristofferC, do you think the test needs to include a working struct TestAbstractString <: AbstractString and call parse(Int, :: TestAbstractString) ? Or would something like this suffice as a minimal failing example? ...

julia> s = SubString("0x")
"0x"

julia> Base.lastindex(s::SubString) = s.string == "0x" ? 1 : thisind(s, s.ncodeunits)

julia> function Base.iterate(s::SubString, i::Integer=firstindex(s))
           i == lastindex(s)+1 && return nothing
#     Was: i == ncodeunits(s)+1 && return nothing

           @boundscheck checkbounds(s, i)
           y = iterate(s.string, s.offset + i)
           y === nothing && return nothing
           c, i = y
           return c, i - s.offset
       end

julia> s
"0"

julia> parse(Int, s)
ERROR: TypeError: in parseint_preamble, in typeassert, expected Tuple{Char,Int64}, got Nothing
Stacktrace:
 [1] parseint_preamble(::Bool, ::Int64, ::SubString{String}, ::Int64, ::Int64) at ./parse.jl:77

@KristofferC
Copy link
Sponsor Member

KristofferC commented Oct 2, 2018

There is an existing tstStringType and also a GenericString in the string tests, would it be possible to modify those to trigger the bug here?

@samoconnor
Copy link
Contributor Author

How about this:

struct Issue29451String <: AbstractString end

Base.ncodeunits(::Issue29451String) = 12345
Base.isvalid(::Issue29451String, i::Integer) = i == 1
Base.lastindex(::Issue29451String) = 1
Base.iterate(::Issue29451String, i::Integer=1) = i == 1 ? ('0', 2) : nothing

@test Issue29451String() == "0"
@test Issue29451String()[1] == '0'
@test isvalid(Issue29451String(), 1)
@test !isvalid(Issue29451String(), 2)
@test parse(Int, Issue29451String()) == 0

Or even

struct Issue29451String <: AbstractString end

Base.ncodeunits(::Issue29451String) = 12345
Base.lastindex(::Issue29451String) = 1
Base.iterate(::Issue29451String, i::Integer=1) = i == 1 ? ('0', 2) : nothing

@test Issue29451String() == "0"
@test parse(Int, Issue29451String()) == 0

@StefanKarpinski
Copy link
Sponsor Member

Nice test case! Looks good to me once it passes tests.

@fredrikekre fredrikekre changed the title Fix #29451 Fix #29451: parse(Int, s::AbstractString) when ncodeunits(s) > lastindex(s) Oct 2, 2018
@samoconnor
Copy link
Contributor Author

CI looks good except for something about rmtmpdir and Pkg/pkg on Windows. Unrelated?

@JeffBezanson JeffBezanson merged commit a984ad0 into JuliaLang:master Oct 3, 2018
@KristofferC KristofferC added domain:strings "Strings!" kind:bugfix This change fixes an existing bug backport pending 1.0 and removed needs tests Unit tests are required for this change labels Oct 3, 2018
Keno added a commit that referenced this pull request Oct 3, 2018
KristofferC pushed a commit that referenced this pull request Oct 6, 2018
KristofferC pushed a commit that referenced this pull request Feb 11, 2019
KristofferC pushed a commit that referenced this pull request Feb 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:strings "Strings!" kind:bugfix This change fixes an existing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants