Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::
return n
end

function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}},
function tryparse_internal(::Type{Bool}, sbuff::AbstractString,
startpos::Int, endpos::Int, base::Integer, raise::Bool)
if isempty(sbuff)
raise && throw(ArgumentError("input string is empty"))
Expand All @@ -202,10 +202,15 @@ function tryparse_internal(::Type{Bool}, sbuff::Union{String,SubString{String}},
end

len = endpos - startpos + 1
p = pointer(sbuff) + startpos - 1
GC.@preserve sbuff begin
(len == 4) && (0 == _memcmp(p, "true", 4)) && (return true)
(len == 5) && (0 == _memcmp(p, "false", 5)) && (return false)
if sbuff isa Union{String, SubString{String}}
p = pointer(sbuff) + startpos - 1
GC.@preserve sbuff begin
(len == 4) && (0 == _memcmp(p, "true", 4)) && (return true)
(len == 5) && (0 == _memcmp(p, "false", 5)) && (return false)
end
else
(len == 4) && (SubString(sbuff, startpos:startpos+3) == "true") && (return true)
(len == 5) && (SubString(sbuff, startpos:startpos+4) == "false") && (return false)
end

if raise
Expand Down
10 changes: 10 additions & 0 deletions test/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ Base.iterate(::Issue29451String, i::Integer=1) = i == 1 ? ('0', 2) : nothing
@test Issue29451String() == "0"
@test parse(Int, Issue29451String()) == 0

# https://github.com/JuliaStrings/InlineStrings.jl/issues/57
struct InlineStringIssue57 <: AbstractString end
Base.ncodeunits(::InlineStringIssue57) = 4
Base.lastindex(::InlineStringIssue57) = 4
Base.isvalid(::InlineStringIssue57, i::Integer) = 0 < i < 5
Base.iterate(::InlineStringIssue57, i::Integer=1) = i == 1 ? ('t', 2) : i == 2 ? ('r', 3) : i == 3 ? ('u', 4) : i == 4 ? ('e', 5) : nothing
Base.:(==)(::SubString{InlineStringIssue57}, x::String) = x == "true"

@test parse(Bool, InlineStringIssue57())

@testset "Issue 20587, T=$T" for T in Any[BigInt, Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8]
T === BigInt && continue # TODO: make BigInt pass this test
for s in ["", " ", " "]
Expand Down