diff --git a/net/http/escapejsstringliteral.c b/net/http/escapejsstringliteral.c index f654edc5c..5d0355b3e 100644 --- a/net/http/escapejsstringliteral.c +++ b/net/http/escapejsstringliteral.c @@ -27,7 +27,7 @@ static const char kEscapeLiteral[128] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 2, 9, 4, 3, 9, 9, // 0x00 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 0x10 - 0, 0, 7, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, 0, 0, 6, // 0x20 + 0, 0, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 6, // 0x20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, // 0x30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, // 0x50 @@ -39,6 +39,8 @@ static const char kEscapeLiteral[128] = { * Escapes UTF-8 data for JavaScript or JSON string literal. * * HTML entities and forward slash are escaped too for added safety. + * Single quote (`'`) is \uxxxx-encoded for consistency, as it's + * allowed in JavaScript, but not in JSON strings. * * We assume the UTF-8 is well-formed and can be represented as UTF-16. * Things that can't be decoded will fall back to binary. Things that diff --git a/test/tool/net/encodejson_test.lua b/test/tool/net/encodejson_test.lua index b647ab370..edd97df91 100644 --- a/test/tool/net/encodejson_test.lua +++ b/test/tool/net/encodejson_test.lua @@ -44,7 +44,7 @@ assert(EncodeJson("\r") == [["\r"]]) assert(EncodeJson("\n") == [["\n"]]) assert(EncodeJson("\f") == [["\f"]]) assert(EncodeJson("\"") == [["\""]]) -assert(EncodeJson("\'") == [["\'"]]) +assert(EncodeJson("\'") == [["\u0027"]]) assert(EncodeJson("\\") == [["\\"]]) assert(EncodeJson( diff --git a/test/tool/net/ljson_test.lua b/test/tool/net/ljson_test.lua index a51df4eb6..13d628733 100644 --- a/test/tool/net/ljson_test.lua +++ b/test/tool/net/ljson_test.lua @@ -37,12 +37,18 @@ assert(EncodeJson(assert(DecodeJson[[ true ]])) == 'true') assert(EncodeJson(assert(DecodeJson[[ [] ]])) == '[]') assert(EncodeJson(assert(DecodeJson[[ {} ]])) == '{}') +for c = 0, 127 do + assert(DecodeJson(assert(EncodeJson(string.char(c)))) == string.char(c)) +end + assert(assert(DecodeJson[["\f"]]) == '\f') -- c0 assert(assert(DecodeJson[["\t"]]) == '\t') -- c0 assert(assert(DecodeJson[["\n"]]) == '\n') -- c0 assert(assert(DecodeJson[["\r"]]) == '\r') -- c0 assert(assert(DecodeJson[["\\"]]) == '\\') -- c0 assert(assert(DecodeJson[["\""]]) == '\"') -- c0 +assert(DecodeJson(EncodeJson"it's wonderful") == "it's wonderful") +assert(EncodeJson"it's wonderful" == '"it\\u0027s wonderful"') assert(assert(DecodeJson[["\u0100"]]) == 'Ā') -- latin-1 assert(assert(DecodeJson[["\ud800\udf30\ud800\udf30"]]) == '𐌰𐌰') -- utf-16 astral planes gothic assert(assert(DecodeJson[["\uD800"]]) == '\\uD800') -- utf-16 invalid (keep utf-8 well-formed)