Added ARDUINOJSON_ENABLE_COMMENTS to enable support for comments

This commit is contained in:
Benoit Blanchon
2020-01-13 18:16:02 +01:00
parent f9cfea244a
commit 04fe7e1a27
11 changed files with 488 additions and 393 deletions

View File

@ -6,11 +6,24 @@ HEAD
* Added `BasicJsonDocument::shrinkToFit()` * Added `BasicJsonDocument::shrinkToFit()`
* Added support of `uint8_t` for `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` (issue #1142) * Added support of `uint8_t` for `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` (issue #1142)
* Added `ARDUINOJSON_ENABLE_COMMENTS` to enable support for comments (defaults to 0)
* Auto enable support for `std::string` and `std::stream` on modern compilers (issue #1156) * Auto enable support for `std::string` and `std::stream` on modern compilers (issue #1156)
(No need to define `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_STD_STREAM` anymore) (No need to define `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_STD_STREAM` anymore)
* Improved decoding of UTF-16 surrogate pairs (PR #1157 by @kaysievers) * Improved decoding of UTF-16 surrogate pairs (PR #1157 by @kaysievers)
(ArduinoJson now produces standard UTF-8 instead of CESU-8) (ArduinoJson now produces standard UTF-8 instead of CESU-8)
> ### BREAKING CHANGES
>
> #### Comments
>
> Support for comments in input is now optional and disabled by default.
>
> If you need support for comments, you must defined `ARDUINOJSON_ENABLE_COMMENTS` to `1`; otherwise, you'll receive `InvalidInput` errors.
>
> ```c++
> #define ARDUINOJSON_ENABLE_COMMENTS 1
> #include <ArduinoJson.h>
> ```
v6.13.0 (2019-11-01) v6.13.0 (2019-11-01)
------- -------

View File

@ -170,155 +170,6 @@ TEST_CASE("deserialize JSON array") {
} }
} }
SECTION("Block comments") {
SECTION("Before opening bracket") {
DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ [\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After opening bracket") {
DeserializationError err =
deserializeJson(doc, "[/*COMMENT*/ \"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("/*/") {
DeserializationError err = deserializeJson(doc, "[/*/\n]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Unfinished comment") {
DeserializationError err = deserializeJson(doc, "[/*COMMENT]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Final slash missing") {
DeserializationError err = deserializeJson(doc, "[/*COMMENT*]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
}
SECTION("Trailing comments") {
SECTION("Before opening bracket") {
DeserializationError err =
deserializeJson(doc, "//COMMENT\n\t[\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After opening bracket") {
DeserializationError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before closing bracket") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\r\n]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("Invalid comment") {
DeserializationError err = deserializeJson(doc, "[/COMMENT\n]");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("End document with comment") {
DeserializationError err = deserializeJson(doc, "[//COMMENT");
REQUIRE(err == DeserializationError::IncompleteInput);
}
}
SECTION("Premature null-terminator") { SECTION("Premature null-terminator") {
SECTION("After opening bracket") { SECTION("After opening bracket") {
DeserializationError err = deserializeJson(doc, "["); DeserializationError err = deserializeJson(doc, "[");

View File

@ -41,7 +41,7 @@ TEST_CASE("deserializeJson(std::istream&)") {
DynamicJsonDocument doc(4096); DynamicJsonDocument doc(4096);
SECTION("array") { SECTION("array") {
std::istringstream json(" [ 42 /* comment */ ] "); std::istringstream json(" [ 42 ] ");
DeserializationError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
JsonArray arr = doc.as<JsonArray>(); JsonArray arr = doc.as<JsonArray>();
@ -52,7 +52,7 @@ TEST_CASE("deserializeJson(std::istream&)") {
} }
SECTION("object") { SECTION("object") {
std::istringstream json(" { hello : 'world' // comment\n }"); std::istringstream json(" { hello : 'world' }");
DeserializationError err = deserializeJson(doc, json); DeserializationError err = deserializeJson(doc, json);
JsonObject obj = doc.as<JsonObject>(); JsonObject obj = doc.as<JsonObject>();

View File

@ -61,26 +61,6 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
} }
} }
SECTION("Comments") {
SECTION("Just a trailing comment") {
DeserializationError err = deserializeJson(doc, "// comment");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Just a block comment") {
DeserializationError err = deserializeJson(doc, "/*comment*/");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Just a slash") {
DeserializationError err = deserializeJson(doc, "/");
REQUIRE(err == DeserializationError::InvalidInput);
}
}
SECTION("Premature null-terminator") { SECTION("Premature null-terminator") {
SECTION("In escape sequence") { SECTION("In escape sequence") {
DeserializationError err = deserializeJson(doc, "\"\\"); DeserializationError err = deserializeJson(doc, "\"\\");
@ -88,12 +68,6 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
REQUIRE(err == DeserializationError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In block comment") {
DeserializationError err = deserializeJson(doc, "/* comment");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("In double quoted string") { SECTION("In double quoted string") {
DeserializationError err = deserializeJson(doc, "\"hello"); DeserializationError err = deserializeJson(doc, "\"hello");
@ -114,12 +88,6 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
REQUIRE(err == DeserializationError::IncompleteInput); REQUIRE(err == DeserializationError::IncompleteInput);
} }
SECTION("In block comment") {
DeserializationError err = deserializeJson(doc, "/* comment */", 10);
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("In double quoted string") { SECTION("In double quoted string") {
DeserializationError err = deserializeJson(doc, "\"hello\"", 6); DeserializationError err = deserializeJson(doc, "\"hello\"", 6);

View File

@ -281,212 +281,6 @@ TEST_CASE("deserialize JSON object") {
} }
} }
SECTION("Block comments") {
SECTION("Before opening brace") {
DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
DeserializationError err =
deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Trailing comments") {
SECTION("Before opening brace") {
DeserializationError err =
deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
DeserializationError err =
deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Dangling slash") {
SECTION("Before opening brace") {
DeserializationError err = deserializeJson(doc, "/{\"hello\":\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After opening brace") {
DeserializationError err = deserializeJson(doc, "{/\"hello\":\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("Before colon") {
DeserializationError err = deserializeJson(doc, "{\"hello\"/:\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After colon") {
DeserializationError err = deserializeJson(doc, "{\"hello\":/\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("Before closing brace") {
DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After closing brace") {
DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"}/");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}");
REQUIRE(err == DeserializationError::InvalidInput);
}
}
SECTION("Should clear the JsonObject") { SECTION("Should clear the JsonObject") {
deserializeJson(doc, "{\"hello\":\"world\"}"); deserializeJson(doc, "{\"hello\":\"world\"}");
deserializeJson(doc, "{}"); deserializeJson(doc, "{}");

View File

@ -18,6 +18,8 @@ add_executable(MixedConfigurationTests
use_long_long_0.cpp use_long_long_0.cpp
use_long_long_1.cpp use_long_long_1.cpp
enable_progmem_1.cpp enable_progmem_1.cpp
enable_comments_1.cpp
enable_comments_0.cpp
) )
target_link_libraries(MixedConfigurationTests catch) target_link_libraries(MixedConfigurationTests catch)

View File

@ -0,0 +1,54 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2020
// MIT License
#define ARDUINOJSON_ENABLE_COMMENTS 0
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("Comments should produce InvalidInput") {
DynamicJsonDocument doc(2048);
const char* testCases[] = {
"/*COMMENT*/ [\"hello\"]",
"[/*COMMENT*/ \"hello\"]",
"[\"hello\"/*COMMENT*/]",
"[\"hello\"/*COMMENT*/,\"world\"]",
"[\"hello\",/*COMMENT*/ \"world\"]",
"[/*/\n]",
"[/*COMMENT]",
"[/*COMMENT*]",
"//COMMENT\n\t[\"hello\"]",
"[//COMMENT\n\"hello\"]",
"[\"hello\"//COMMENT\r\n]",
"[\"hello\"//COMMENT\n,\"world\"]",
"[\"hello\",//COMMENT\n\"world\"]",
"[/COMMENT\n]",
"[//COMMENT",
"/*COMMENT*/ {\"hello\":\"world\"}",
"{/*COMMENT*/\"hello\":\"world\"}",
"{\"hello\"/*COMMENT*/:\"world\"}",
"{\"hello\":/*COMMENT*/\"world\"}",
"{\"hello\":\"world\"/*COMMENT*/}",
"//COMMENT\n {\"hello\":\"world\"}",
"{//COMMENT\n\"hello\":\"world\"}",
"{\"hello\"//COMMENT\n:\"world\"}",
"{\"hello\"://COMMENT\n\"world\"}",
"{\"hello\":\"world\"//COMMENT\n}",
"/{\"hello\":\"world\"}",
"{/\"hello\":\"world\"}",
"{\"hello\"/:\"world\"}",
"{\"hello\":/\"world\"}",
"{\"hello\":\"world\"/}",
"{\"hello\":\"world\"/,\"answer\":42}",
"{\"hello\":\"world\",/\"answer\":42}",
};
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
for (size_t i = 0; i < testCount; i++) {
const char* input = testCases[i];
CAPTURE(input);
REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
}
}

View File

@ -0,0 +1,405 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2020
// MIT License
#define ARDUINOJSON_ENABLE_COMMENTS 1
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("Comments in arrays") {
DynamicJsonDocument doc(2048);
SECTION("Block comments") {
SECTION("Before opening bracket") {
DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ [\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After opening bracket") {
DeserializationError err =
deserializeJson(doc, "[/*COMMENT*/ \"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("/*/") {
DeserializationError err = deserializeJson(doc, "[/*/\n]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Unfinished comment") {
DeserializationError err = deserializeJson(doc, "[/*COMMENT]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Final slash missing") {
DeserializationError err = deserializeJson(doc, "[/*COMMENT*]");
REQUIRE(err == DeserializationError::IncompleteInput);
}
}
SECTION("Trailing comments") {
SECTION("Before opening bracket") {
DeserializationError err =
deserializeJson(doc, "//COMMENT\n\t[\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After opening bracket") {
DeserializationError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before closing bracket") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\r\n]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("After closing bracket") {
DeserializationError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("Invalid comment") {
DeserializationError err = deserializeJson(doc, "[/COMMENT\n]");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("End document with comment") {
DeserializationError err = deserializeJson(doc, "[//COMMENT");
REQUIRE(err == DeserializationError::IncompleteInput);
}
}
}
TEST_CASE("Comments in objects") {
DynamicJsonDocument doc(2048);
SECTION("Block comments") {
SECTION("Before opening brace") {
DeserializationError err =
deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
DeserializationError err =
deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Trailing comments") {
SECTION("Before opening brace") {
DeserializationError err =
deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
DeserializationError err =
deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
DeserializationError err =
deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
DeserializationError err = deserializeJson(
doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Dangling slash") {
SECTION("Before opening brace") {
DeserializationError err = deserializeJson(doc, "/{\"hello\":\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After opening brace") {
DeserializationError err = deserializeJson(doc, "{/\"hello\":\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("Before colon") {
DeserializationError err = deserializeJson(doc, "{\"hello\"/:\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After colon") {
DeserializationError err = deserializeJson(doc, "{\"hello\":/\"world\"}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("Before closing brace") {
DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After closing brace") {
DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"}/");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("After comma") {
DeserializationError err =
deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}");
REQUIRE(err == DeserializationError::InvalidInput);
}
}
}
TEST_CASE("Comments alone") {
DynamicJsonDocument doc(2048);
SECTION("Just a trailing comment") {
DeserializationError err = deserializeJson(doc, "// comment");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Just a block comment") {
DeserializationError err = deserializeJson(doc, "/*comment*/");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Just a slash") {
DeserializationError err = deserializeJson(doc, "/");
REQUIRE(err == DeserializationError::InvalidInput);
}
SECTION("Premature terminator") {
DeserializationError err = deserializeJson(doc, "/* comment");
REQUIRE(err == DeserializationError::IncompleteInput);
}
SECTION("Premature end on sized input") {
DeserializationError err = deserializeJson(doc, "/* comment */", 10);
REQUIRE(err == DeserializationError::IncompleteInput);
}
}

View File

@ -165,6 +165,11 @@
#define ARDUINOJSON_DECODE_UNICODE 0 #define ARDUINOJSON_DECODE_UNICODE 0
#endif #endif
// Ignore comments in input
#ifndef ARDUINOJSON_ENABLE_COMMENTS
#define ARDUINOJSON_ENABLE_COMMENTS 0
#endif
// Support NaN in JSON // Support NaN in JSON
#ifndef ARDUINOJSON_ENABLE_NAN #ifndef ARDUINOJSON_ENABLE_NAN
#define ARDUINOJSON_ENABLE_NAN 0 #define ARDUINOJSON_ENABLE_NAN 0

View File

@ -357,6 +357,7 @@ class JsonDeserializer {
move(); move();
continue; continue;
#if ARDUINOJSON_ENABLE_COMMENTS
// comments // comments
case '/': case '/':
move(); // skip '/' move(); // skip '/'
@ -394,6 +395,7 @@ class JsonDeserializer {
return DeserializationError::InvalidInput; return DeserializationError::InvalidInput;
} }
break; break;
#endif
default: default:
return DeserializationError::Ok; return DeserializationError::Ok;

View File

@ -14,13 +14,14 @@
#define ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, H) \ #define ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, H) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \ ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \
ARDUINOJSON_CONCAT4(E, F, G, H)) ARDUINOJSON_CONCAT4(E, F, G, H))
#define ARDUINOJSON_CONCAT11(A, B, C, D, E, F, G, H, I, J, K) \ #define ARDUINOJSON_CONCAT12(A, B, C, D, E, F, G, H, I, J, K, L) \
ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, ARDUINOJSON_CONCAT4(H, I, J, K)) ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, \
ARDUINOJSON_CONCAT4(H, I, J, ARDUINOJSON_CONCAT2(K, L)))
#define ARDUINOJSON_NAMESPACE \ #define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT11( \ ARDUINOJSON_CONCAT12( \
ArduinoJson, ARDUINOJSON_VERSION_MAJOR, ARDUINOJSON_VERSION_MINOR, \ ArduinoJson, ARDUINOJSON_VERSION_MAJOR, ARDUINOJSON_VERSION_MINOR, \
ARDUINOJSON_VERSION_REVISION, _, ARDUINOJSON_USE_LONG_LONG, \ ARDUINOJSON_VERSION_REVISION, _, ARDUINOJSON_USE_LONG_LONG, \
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE, \ ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE, \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \ ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_PROGMEM) ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_ENABLE_COMMENTS)