8000 Detect IncompleteInput in "true", "false", and "null" · java64/ArduinoJson@abc8819 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit abc8819

Browse files
committed
Detect IncompleteInput in "true", "false", and "null"
1 parent e9b4c62 commit abc8819

File tree

5 files changed

+89
-40
lines changed

5 files changed

+89
-40
lines changed

src/ArduinoJson/Json/JsonDeserializer.hpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ class JsonDeserializer {
6969
return true;
7070
}
7171

72+
DeserializationError eat(const char *s) {
73+
while (*s) {
74+
if (current() == 0) return DeserializationError::IncompleteInput;
75+
if (current() != *s) return DeserializationError::InvalidInput;
76+
move();
77+
s++;
78+
}
79+
return DeserializationError::Ok;
80+
}
81+
7282
DeserializationError parseArray(CollectionData &array) {
7383
if (_nestingLimit == 0) return DeserializationError::TooDeep;
7484

@@ -155,10 +165,18 @@ class JsonDeserializer {
155165
}
156166

157167
DeserializationError parseValue(VariantData &variant) {
158-
if (isQuote(current())) {
159-
return parseStringValue(variant);
160-
} else {
161-
return parseNumericValue(variant);
168+
switch (current()) {
169+
case '\'':
170+
case '\"':
171+
return parseStringValue(variant);
172+
case 'n':
173+
return parseNull();
174+
case 'f':
175+
return parseFalse(variant);
176+
case 't':
177+
return parseTrue(variant);
178+
default:
179+
return parseNumericValue(variant);
162180
}
163181
}
164182

@@ -240,6 +258,23 @@ class JsonDeserializer {
240258
return DeserializationError::Ok;
241259
}
242260

261+
DeserializationError parseTrue(VariantData &result) {
262+
DeserializationError err = eat("true");
263+
if (!err) result.setBoolean(true);
264+
return err;
265+
}
266+
267+
DeserializationError parseFalse(VariantData &result) {
268+
DeserializationError err = eat("false");
269+
if (!err) result.setBoolean(false);
270+
return err;
271+
}
272+
273+
DeserializationError parseNull() {
274+
DeserializationError err = eat("null");
275+
return err;
276+
}
277+
243278
DeserializationError parseNumericValue(VariantData &result) {
244279
char buffer[64];
245280
uint8_t n = 0;
@@ -256,12 +291,6 @@ class JsonDeserializer {
256291
result.setInteger(parseInteger<Integer>(buffer));
257292
} else if (isFloat(buffer)) {
258293
result.setFloat(parseFloat<Float>(buffer));
259-
} else if (!strcmp(buffer, "true")) {
260-
result.setBoolean(true);
261-
} else if (!strcmp(buffer, "false")) {
262-
result.setBoolean(false);
263-
} else if (!strcmp(buffer, "null")) {
264-
// already null
265294
} else {
266295
return DeserializationError::InvalidInput;
267296
}

test/JsonDeserializer/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ add_executable(JsonDeserializerTests
1111
deserializeJsonValue.cpp
1212
deserializeJsonString.cpp
1313
input_types.cpp
14+
incomplete_input.cpp
15+
invalid_input.cpp
1416
nestingLimit.cpp
1517
)
1618

test/JsonDeserializer/deserializeJsonString.cpp

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include <ArduinoJson.h>
77
#include <catch.hpp>
88

9-
using namespace Catch::Matchers;
10-
119
TEST_CASE("Valid JSON strings value") {
1210
struct TestCase {
1311
const char* input;
@@ -36,31 +34,3 @@ TEST_CASE("Valid JSON strings value") {
3634
REQUIRE(doc.as<std::string>() == testCase.expectedOutput);
3735
}
3836
}
39-
40-
TEST_CASE("Truncated JSON string") {
41-
const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"};
42-
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
43-
44-
DynamicJsonDocument doc(4096);
45-
46-
for (size_t i = 0; i < testCount; i++) {
47-
const char* input = testCases[i];
48-
CAPTURE(input);
49-
REQUIRE(deserializeJson(doc, input) ==
50-
DeserializationError::IncompleteInput);
51-
}
52-
}
53-
54-
TEST_CASE("Invalid JSON string") {
55-
const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
56-
"'\\u000G'", "'\\u000/'", "\\x1234"};
57-
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
58-
59-
DynamicJsonDocument doc(4096);
60-
61-
for (size_t i = 0; i < testCount; i++) {
62-
const char* input = testCases[i];
63-
CAPTURE(input);
64-
REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
65-
}
66-
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// ArduinoJson - arduinojson.org
2+
// Copyright Benoit Blanchon 2014-2019
3+
// MIT License
4+
5+
#define ARDUINOJSON_DECODE_UNICODE 1
6+
#include <ArduinoJson.h>
7+
#include <catch.hpp>
8+
9+
TEST_CASE("Truncated JSON input") {
10+
const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000",
11+
// false
12+
"f", "fa", "fal", "fals",
13+
// true
14+
"t", "tr", "tru",
15+
// null
16+
"n", "nu", "nul"};
17+
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
18+
19+
DynamicJsonDocument doc(4096);
20+
21+
for (size_t i = 0; i < testCount; i++) {
22+
const char* input = testCases[i];
23+
CAPTURE(input);
24+
REQUIRE(deserializeJson(doc, input) ==
25+
DeserializationError::IncompleteInput);
26+
}
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ArduinoJson - arduinojson.org
2+
// Copyright Benoit Blanchon 2014-2019
3+
// MIT License
4+
5+
#define ARDUINOJSON_DECODE_UNICODE 1
6+
#include <ArduinoJson.h>
7+
#include <catch.hpp>
8+
9+
TEST_CASE("Invalid JSON input") {
10+
const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
11+
"'\\u000G'", "'\\u000/'", "\\x1234"};
12+
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
13+
14+
DynamicJsonDocument doc(4096);
15+
16+
for (size_t i = 0; i < testCount; i++) {
17+
const char* input = testCases[i];
18+
CAPTURE(input);
19+
REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput);
20+
}
21+
}

0 commit comments

Comments
 (0)
0