Detect IncompleteInput in false, true, and null

This commit is contained in:
Benoit Blanchon
2019-02-18 16:18:11 +01:00
parent 56bf24e1ec
commit 4181de119c
6 changed files with 86 additions and 13 deletions

View File

@ -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)
----------- -----------

View File

@ -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) {

View File

@ -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
) )

View File

@ -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;

View 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);
}
}

View 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);
}
}