This is a bit of an edge case, but it seems to be handled in other platforms (to varying degrees).
The simplest explanation I can give you is just to show you this code:
#include <string>
#include "json.hpp"
using json = nlohmann::json;
int main(int argc, const char **argv) {
std::string encoded("\u0006\u00e4\u00b4\u00d8\u008d\"");
auto j3 = json::parse(encoded);
}
Which produced this exception:
JSON Exception: [json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read: '<U+0006>'test complete.
Note: the same error occurs when nlohmann has done the previous encoding of the string (as shown below).
Whilst I fully understand the reason for the error, I don't believe that it is valid to assume all strings will be valid UTF-8, merely because the JSON spec includes \u0000 unicode escape sequences. I might be wrong, I haven't read the RFC lately.
Ignore everything below this line, as it's just more details. :)
Expanded tests
int main(int argc, const char **argv) {
// binary string, not valid utf-8
std::string ugly("\x06\xe4\xb4\xd8\x8d\x22");
// will encode okay
json j = {{ "text", ugly.c_str() }};
printf("encoding complete.\n"); fflush(stdout);
// 2.1.1 can dump okay
// dumping: {"text":"\u0006▒؍\""}
// 3.2.0 will trigger exception when dumping
printf("dumping: %s\n", j.dump().c_str()); fflush(stdout);
// both will trigger exception when parsing
auto j2 = json::parse(j.dump());
printf("test complete.\n"); fflush(stdout);
Some tests with other platforms showed that php will not encode a raw non-UTF8 binary string, JavaScript (v8) had no issues, and python actually produced the "every character escaped" version I used in the initial example.
// JavaScript tests (performed in Chrome console window)
// helper functions from: https://nt4.com/js/hexdump.js
/*
* > j = JSON.stringify(sprintf("\x06\xe4\xb4\xd8\x8d\x22"))
* < ""\u0006䴨�\"""
*
* > hexdump(j)
* < 0000000: 22 5c 75 30 30 30 36 e4 b4 d8 8d 5c 22 22 "\u0006....\""
*
* > JSON.parse(j)
* < "�䴨�""
*
* > hexdump(JSON.parse(j))
* < 0000000: 06 e4 b4 d8 8d 22 ....."
*/
PHP test:
// PHP test (performed from bash shell, with the aid of a private helper)
// (encode fails, but decode succeeds)
/*
* root@ec js $ echo -ne "\x06\xe4\xb4\xd8\x8d\x22" | phpparse - json_encode
* false
*
* root@ec js $ echo -n '"\u0006䴨�\""' | phpparse - json_decode
* 䴨�"
*/
}
This is a bit of an edge case, but it seems to be handled in other platforms (to varying degrees).
The simplest explanation I can give you is just to show you this code:
Which produced this exception:
Note: the same error occurs when nlohmann has done the previous encoding of the string (as shown below).
Whilst I fully understand the reason for the error, I don't believe that it is valid to assume all strings will be valid UTF-8, merely because the JSON spec includes
\u0000unicode escape sequences. I might be wrong, I haven't read the RFC lately.Ignore everything below this line, as it's just more details. :)
Expanded tests
Some tests with other platforms showed that
phpwill not encode a raw non-UTF8 binary string,JavaScript (v8)had no issues, andpythonactually produced the "every character escaped" version I used in the initial example.PHP test: