forked from bblanchon/ArduinoJson
Detect IncompleteInput
in false
, true
, and null
This commit is contained in:
@ -15,6 +15,7 @@ HEAD
|
|||||||
* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()`
|
* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()`
|
||||||
* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)`
|
* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)`
|
||||||
* Fixed segfault after `variant.set(serialized((char*)0))`
|
* Fixed segfault after `variant.set(serialized((char*)0))`
|
||||||
|
* Detect `IncompleteInput` in `false`, `true`, and `null`
|
||||||
|
|
||||||
v6.8.0-beta (2019-01-30)
|
v6.8.0-beta (2019-01-30)
|
||||||
-----------
|
-----------
|
||||||
|
@ -253,18 +253,29 @@ class JsonDeserializer {
|
|||||||
|
|
||||||
if (isInteger(buffer)) {
|
if (isInteger(buffer)) {
|
||||||
result.setInteger(parseInteger<Integer>(buffer));
|
result.setInteger(parseInteger<Integer>(buffer));
|
||||||
} else if (isFloat(buffer)) {
|
return DeserializationError::Ok;
|
||||||
result.setFloat(parseFloat<Float>(buffer));
|
|
||||||
} else if (!strcmp(buffer, "true")) {
|
|
||||||
result.setBoolean(true);
|
|
||||||
} else if (!strcmp(buffer, "false")) {
|
|
||||||
result.setBoolean(false);
|
|
||||||
} else if (!strcmp(buffer, "null")) {
|
|
||||||
// already null
|
|
||||||
} else {
|
|
||||||
return DeserializationError::InvalidInput;
|
|
||||||
}
|
}
|
||||||
return DeserializationError::Ok;
|
if (isFloat(buffer)) {
|
||||||
|
result.setFloat(parseFloat<Float>(buffer));
|
||||||
|
return DeserializationError::Ok;
|
||||||
|
}
|
||||||
|
c = buffer[0];
|
||||||
|
if (c == 't') { // true
|
||||||
|
result.setBoolean(true);
|
||||||
|
return n == 4 ? DeserializationError::Ok
|
||||||
|
: DeserializationError::IncompleteInput;
|
||||||
|
}
|
||||||
|
if (c == 'f') { // false
|
||||||
|
result.setBoolean(false);
|
||||||
|
return n == 5 ? DeserializationError::Ok
|
||||||
|
: DeserializationError::IncompleteInput;
|
||||||
|
}
|
||||||
|
if (c == 'n') { // null
|
||||||
|
// the variant is already null
|
||||||
|
return n == 4 ? DeserializationError::Ok
|
||||||
|
: DeserializationError::IncompleteInput;
|
||||||
|
}
|
||||||
|
return DeserializationError::InvalidInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeserializationError parseCodepoint(uint16_t &codepoint) {
|
DeserializationError parseCodepoint(uint16_t &codepoint) {
|
||||||
|
@ -11,6 +11,8 @@ add_executable(JsonDeserializerTests
|
|||||||
deserializeJsonValue.cpp
|
deserializeJsonValue.cpp
|
||||||
deserializeJsonString.cpp
|
deserializeJsonString.cpp
|
||||||
input_types.cpp
|
input_types.cpp
|
||||||
|
incomplete_input.cpp
|
||||||
|
invalid_input.cpp
|
||||||
nestingLimit.cpp
|
nestingLimit.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace Catch::Matchers;
|
|
||||||
|
|
||||||
TEST_CASE("Valid JSON strings value") {
|
TEST_CASE("Valid JSON strings value") {
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
const char* input;
|
const char* input;
|
||||||
|
27
test/JsonDeserializer/incomplete_input.cpp
Normal file
27
test/JsonDeserializer/incomplete_input.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2019
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("Truncated JSON input") {
|
||||||
|
const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000",
|
||||||
|
// false
|
||||||
|
"f", "fa", "fal", "fals",
|
||||||
|
// true
|
||||||
|
"t", "tr", "tru",
|
||||||
|
// null
|
||||||
|
"n", "nu", "nul"};
|
||||||
|
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
|
||||||
|
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < testCount; i++) {
|
||||||
|
const char* input = testCases[i];
|
||||||
|
CAPTURE(input);
|
||||||
|
REQUIRE(deserializeJson(doc, input) ==
|
||||||
|
DeserializationError::IncompleteInput);
|
||||||
|
}
|
||||||
|
}
|
34
test/JsonDeserializer/invalid_input.cpp
Normal file
34
test/JsonDeserializer/invalid_input.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2019
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("Invalid JSON input") {
|
||||||
|
const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
|
||||||
|
"'\\u000G'", "'\\u000/'", "\\x1234"};
|
||||||
|
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
|
||||||
|
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < testCount; i++) {
|
||||||
|
const char* input = testCases[i];
|
||||||
|
CAPTURE(input);
|
||||||
|
REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Invalid JSON input that should pass") {
|
||||||
|
const char* testCases[] = {"nulL", "tru3", "fals3"};
|
||||||
|
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
|
||||||
|
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < testCount; i++) {
|
||||||
|
const char* input = testCases[i];
|
||||||
|
CAPTURE(input);
|
||||||
|
REQUIRE(deserializeJson(doc, input) == DeserializationError::Ok);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user