forked from bblanchon/ArduinoJson
Support NUL inside string values (issue #1646)
This commit is contained in:
@ -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;
|
||||
|
@ -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") {
|
||||
|
@ -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*>") {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user