diff --git a/.vscode/settings.json b/.vscode/settings.json index f94e77f3..5e9d4ec5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,16 @@ "git.inputValidationLength": 80, "git.inputValidationSubjectLength": 72, "files.insertFinalNewline": true, - "files.trimFinalNewlines": true + "files.trimFinalNewlines": true, + "files.associations": { + "fstream": "cpp", + "iomanip": "cpp", + "string": "cpp", + "system_error": "cpp", + "vector": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xstring": "cpp" + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 46819773..38eb4425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ HEAD * Fixed error `'dummy' may be used uninitialized` on GCC 11 * Fixed error `expected unqualified-id before 'const'` on GCC 11 (issue #1622) * Filter: exact match takes precedence over wildcard (issue #1628) +* Fixed deserialization of `\u0000` (issue #1646) v6.18.3 (2021-07-27) ------- diff --git a/extras/tests/JsonDeserializer/string.cpp b/extras/tests/JsonDeserializer/string.cpp index a5dc8f07..5ab87640 100644 --- a/extras/tests/JsonDeserializer/string.cpp +++ b/extras/tests/JsonDeserializer/string.cpp @@ -46,6 +46,25 @@ TEST_CASE("Valid JSON strings value") { } } +TEST_CASE("\\u0000") { + StaticJsonDocument<200> doc; + + DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\""); + REQUIRE(err == DeserializationError::Ok); + + const char* result = doc.as(); + CHECK(result[0] == 'w'); + CHECK(result[1] == 'x'); + CHECK(result[2] == 0); + CHECK(result[3] == 'y'); + CHECK(result[4] == 'z'); + CHECK(result[5] == 0); + + // ArduinoJson strings doesn't store string length, so the following returns 2 + // instead of 5 (issue #1646) + CHECK(doc.as().size() == 2); +} + TEST_CASE("Truncated JSON string") { const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"}; const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); diff --git a/src/ArduinoJson/Json/Utf8.hpp b/src/ArduinoJson/Json/Utf8.hpp index a30f77a8..c8f11036 100644 --- a/src/ArduinoJson/Json/Utf8.hpp +++ b/src/ArduinoJson/Json/Utf8.hpp @@ -13,14 +13,14 @@ template inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) { // this function was optimize for code size on AVR - // a buffer to store the string in reverse - char buf[5]; - char* p = buf; - - *(p++) = 0; if (codepoint32 < 0x80) { - *(p++) = char((codepoint32)); + str.append(char(codepoint32)); } else { + // a buffer to store the string in reverse + char buf[5]; + char* p = buf; + + *(p++) = 0; *(p++) = char((codepoint32 | 0x80) & 0xBF); uint16_t codepoint16 = uint16_t(codepoint32 >> 6); if (codepoint16 < 0x20) { // 0x800 @@ -36,10 +36,10 @@ inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) { *(p++) = char(codepoint16 | 0xF0); } } - } - while (*(--p)) { - str.append(*p); + while (*(--p)) { + str.append(*p); + } } } } // namespace Utf8