Support NUL inside string values (issue #1646)

This commit is contained in:
Benoit Blanchon
2021-11-21 15:07:56 +01:00
parent a27398e445
commit be70f6ddd7
22 changed files with 144 additions and 59 deletions

View File

@ -8,7 +8,7 @@
#endif
TEST_CASE("string_view") {
StaticJsonDocument<128> doc;
StaticJsonDocument<256> doc;
JsonVariant variant = doc.to<JsonVariant>();
SECTION("deserializeJson()") {
@ -57,6 +57,12 @@ TEST_CASE("string_view") {
doc.add(std::string_view("example two", 7));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8);
doc.add(std::string_view("example\0tree", 12));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(3) + 21);
doc.add(std::string_view("example\0tree and a half", 12));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(4) + 21);
}
SECTION("as<std::string_view>()") {
@ -72,6 +78,12 @@ TEST_CASE("string_view") {
REQUIRE(doc["s"].is<std::string_view>() == true);
REQUIRE(doc["i"].is<std::string_view>() == false);
}
SECTION("String containing NUL") {
doc.set(std::string("hello\0world", 11));
REQUIRE(doc.as<std::string_view>().size() == 11);
REQUIRE(doc.as<std::string_view>() == std::string_view("hello\0world", 11));
}
}
using ARDUINOJSON_NAMESPACE::adaptString;

View File

@ -60,9 +60,8 @@ TEST_CASE("\\u0000") {
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<std::string>().size() == 2);
CHECK(doc.as<JsonString>().size() == 5);
CHECK(doc.as<std::string>().size() == 5);
}
TEST_CASE("Truncated JSON string") {

View File

@ -63,6 +63,10 @@ TEST_CASE("serializeJson(JsonVariant)") {
SECTION("Escape tab") {
check(std::string("hello\tworld"), "\"hello\\tworld\"");
}
SECTION("NUL char") {
check(std::string("hello\0world", 11), "\"hello\\u0000world\"");
}
}
SECTION("SerializedValue<const char*>") {

View File

@ -45,3 +45,13 @@ TEST_CASE("serialize JsonObject to std::string") {
REQUIRE("{\r\n \"key\": \"value\"\r\n}" == json);
}
}
TEST_CASE("serialize an std::string containing a NUL") {
StaticJsonDocument<256> doc;
doc.set(std::string("hello\0world", 11));
CHECK(doc.memoryUsage() == 12);
std::string json;
serializeJson(doc, json);
CHECK("\"hello\\u0000world\"" == json);
}

View File

@ -12,6 +12,10 @@ static const char *saveString(MemoryPool &pool, const char *s) {
return pool.saveString(adaptString(const_cast<char *>(s)));
}
static const char *saveString(MemoryPool &pool, const char *s, size_t n) {
return pool.saveString(adaptString(s, n));
}
TEST_CASE("MemoryPool::saveString()") {
char buffer[32];
MemoryPool pool(buffer, 32);
@ -30,6 +34,27 @@ TEST_CASE("MemoryPool::saveString()") {
REQUIRE(pool.size() == 6);
}
SECTION("Deduplicates identical strings that contain NUL") {
const char *a = saveString(pool, "hello\0world", 11);
const char *b = saveString(pool, "hello\0world", 11);
REQUIRE(a == b);
REQUIRE(pool.size() == 12);
}
SECTION("Reuse part of a string if it ends with NUL") {
const char *a = saveString(pool, "hello\0world", 11);
const char *b = saveString(pool, "hello");
REQUIRE(a == b);
REQUIRE(pool.size() == 12);
}
SECTION("Don't stop on first NUL") {
const char *a = saveString(pool, "hello");
const char *b = saveString(pool, "hello\0world", 11);
REQUIRE(a != b);
REQUIRE(pool.size() == 18);
}
SECTION("Returns NULL when full") {
REQUIRE(pool.capacity() == 32);