From 68149a3629c09f8e24ad7847cda51f0cb1b20078 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Mon, 26 Jun 2017 12:28:04 +0000 Subject: [PATCH] Fix Issue 17553 - std.json should not do UTF decoding when encoding JSON --- std/json.d | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/std/json.d b/std/json.d index 34ca5e8ad46..600ca9a091f 100644 --- a/std/json.d +++ b/std/json.d @@ -707,7 +707,8 @@ if (isInputRange!T && !isInfinite!T && isSomeChar!(ElementEncodingType!T)) JSONValue root; root.type_tag = JSON_TYPE.NULL; - // UTF decoding is unnecessary when parsing JSON. + // Avoid UTF decoding when possible, as it is unnecessary when + // processing JSON. static if (is(T : const(char)[])) alias Char = char; else @@ -1142,11 +1143,11 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o { auto json = appender!string(); - void toString(string str) @safe + void toStringImpl(Char)(string str) @safe { json.put('"'); - foreach (dchar c; str) + foreach (Char c; str) { switch (c) { @@ -1160,7 +1161,7 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o case '\t': json.put("\\t"); break; default: { - import std.uni : isControl; + import std.ascii : isControl; import std.utf : encode; with (JSONOptions) if (isControl(c) || @@ -1192,6 +1193,16 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o json.put('"'); } + void toString(string str) @safe + { + // Avoid UTF decoding when possible, as it is unnecessary when + // processing JSON. + if (options & JSONOptions.escapeNonAsciiChars) + toStringImpl!dchar(str); + else + toStringImpl!char(str); + } + void toValue(ref in JSONValue value, ulong indentLevel) @safe { void putTabs(ulong additionalIndent = 0) @@ -1813,3 +1824,9 @@ pure nothrow @safe unittest // issue 15884 assert(parseJSON("\"\xFF\"").str == "\xFF"); assert(parseJSON("\"\U0001D11E\"").str == "\U0001D11E"); } + +@safe unittest // issue 17553 +{ + auto v = JSONValue("\xFF"); + assert(toJSON(v) == "\"\xFF\""); +}