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

TOML: fix some printing of special characters #41079

Merged
merged 1 commit into from
Jun 6, 2021
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
38 changes: 36 additions & 2 deletions stdlib/TOML/src/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ import Dates
import Base: @invokelatest
import ..isvalid_barekey_char

function print_toml_escaped(io::IO, s::AbstractString)
for c::AbstractChar in s
if !isvalid(c)
error("TOML print: invalid character $(repr(c)) encountered when printing string")
end
if c == '\b'
Base.print(io, '\\', 'b')
elseif c == '\t'
Base.print(io, '\\', 't')
elseif c == '\n'
Base.print(io, '\\', 'n')
elseif c == '\f'
Base.print(io, '\\', 'f')
elseif c == '\r'
Base.print(io, '\\', 'r')
elseif c == '"'
Base.print(io, '\\', '"')
elseif c == '\\'
Base.print(io, "\\", '\\')
elseif Base.iscntrl(c)
Base.print(io, "\\u")
Base.print(io, string(UInt32(c), base=16, pad=4))
else
Base.print(io, c)
stevengj marked this conversation as resolved.
Show resolved Hide resolved
end
end
end

function printkey(io::IO, keys::Vector{String})
for (i, k) in enumerate(keys)
i != 1 && Base.print(io, ".")
Expand All @@ -13,7 +41,9 @@ function printkey(io::IO, keys::Vector{String})
Base.print(io, "\"\"")
elseif any(!isvalid_barekey_char, k)
# quoted key
Base.print(io, "\"", escape_string(k) ,"\"")
Base.print(io, "\"")
print_toml_escaped(io, k)
Base.print(io, "\"")
else
Base.print(io, k)
end
Expand Down Expand Up @@ -50,7 +80,11 @@ printvalue(f::MbyFunc, io::IO, value::AbstractFloat; _...) =
Base.print(io, isnan(value) ? "nan" :
isinf(value) ? string(value > 0 ? "+" : "-", "inf") :
Float64(value)) # TOML specifies IEEE 754 binary64 for float
printvalue(f::MbyFunc, io::IO, value::AbstractString; _...) = Base.print(io, "\"", escape_string(value), "\"")
function printvalue(f::MbyFunc, io::IO, value::AbstractString; _...)
Base.print(io, "\"")
print_toml_escaped(io, value)
Base.print(io, "\"")
end

is_table(value) = isa(value, AbstractDict)
is_array_of_tables(value) = isa(value, AbstractArray) &&
Expand Down
11 changes: 11 additions & 0 deletions stdlib/TOML/test/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ end
d = TOML.parse(s)
@test toml_str(d) == "user = \"me\"\n\n[julia]\n\n[option]\n"
end

@testset "special characters" begin
s = """
"\U1f355 \0 \x0 \x1 \t \b" = "\U1f355 \0 \x0 \x1 \t \b"
"\x7f" = "\x7f"
"""
@test roundtrip(s)

d = Dict("str" => string(Char(0xd800)))
@test_throws ErrorException TOML.print(d)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to have introduced this defect in the test output:

TOML                               (41) |    31.70 |   0.67 |  2.1 |    1230.28 |  1353.48
      From worker 41:   str = "
Suggested change
@test_throws ErrorException TOML.print(d)
@test_throws ErrorException TOML.print(devnull, d)

end