Skip to content

Commit f761c1f

Browse files
committed
fix some printing of special characters (#25)
* fix some printing of special characters
1 parent 9f32653 commit f761c1f

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

stdlib/TOML/src/print.jl

+36-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,34 @@ import Dates
55
import Base: @invokelatest
66
import ..isvalid_barekey_char
77

8+
function print_toml_escaped(io::IO, s::AbstractString)
9+
for c::AbstractChar in s
10+
if !isvalid(c)
11+
error("TOML print: invalid character $(repr(c)) encountered when printing string")
12+
end
13+
if c == '\b'
14+
Base.print(io, '\\', 'b')
15+
elseif c == '\t'
16+
Base.print(io, '\\', 't')
17+
elseif c == '\n'
18+
Base.print(io, '\\', 'n')
19+
elseif c == '\f'
20+
Base.print(io, '\\', 'f')
21+
elseif c == '\r'
22+
Base.print(io, '\\', 'r')
23+
elseif c == '"'
24+
Base.print(io, '\\', '"')
25+
elseif c == '\\'
26+
Base.print(io, "\\", '\\')
27+
elseif Base.iscntrl(c)
28+
Base.print(io, "\\u")
29+
Base.print(io, string(UInt32(c), base=16, pad=4))
30+
else
31+
Base.print(io, c)
32+
end
33+
end
34+
end
35+
836
function printkey(io::IO, keys::Vector{String})
937
for (i, k) in enumerate(keys)
1038
i != 1 && Base.print(io, ".")
@@ -13,7 +41,9 @@ function printkey(io::IO, keys::Vector{String})
1341
Base.print(io, "\"\"")
1442
elseif any(!isvalid_barekey_char, k)
1543
# quoted key
16-
Base.print(io, "\"", escape_string(k) ,"\"")
44+
Base.print(io, "\"")
45+
print_toml_escaped(io, k)
46+
Base.print(io, "\"")
1747
else
1848
Base.print(io, k)
1949
end
@@ -50,7 +80,11 @@ printvalue(f::MbyFunc, io::IO, value::AbstractFloat; _...) =
5080
Base.print(io, isnan(value) ? "nan" :
5181
isinf(value) ? string(value > 0 ? "+" : "-", "inf") :
5282
Float64(value)) # TOML specifies IEEE 754 binary64 for float
53-
printvalue(f::MbyFunc, io::IO, value::AbstractString; _...) = Base.print(io, "\"", escape_string(value), "\"")
83+
function printvalue(f::MbyFunc, io::IO, value::AbstractString; _...)
84+
Base.print(io, "\"")
85+
print_toml_escaped(io, value)
86+
Base.print(io, "\"")
87+
end
5488

5589
is_table(value) = isa(value, AbstractDict)
5690
is_array_of_tables(value) = isa(value, AbstractArray) &&

stdlib/TOML/test/print.jl

+11
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@ end
6060
d = TOML.parse(s)
6161
@test toml_str(d) == "user = \"me\"\n\n[julia]\n\n[option]\n"
6262
end
63+
64+
@testset "special characters" begin
65+
s = """
66+
"\U1f355 \0 \x0 \x1 \t \b" = "\U1f355 \0 \x0 \x1 \t \b"
67+
"\x7f" = "\x7f"
68+
"""
69+
@test roundtrip(s)
70+
71+
d = Dict("str" => string(Char(0xd800)))
72+
@test_throws ErrorException TOML.print(d)
73+
end

0 commit comments

Comments
 (0)