8000 Fixed `JsonBuffer::parse()` nesting limit (fixes #693) · java64/ArduinoJson@3523296 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3523296

Browse files
committed
Fixed JsonBuffer::parse() nesting limit (fixes bblanchon#693)
1 parent 689ae5c commit 3523296

File tree

4 files changed

+62
-42
lines changed

4 files changed

+62
-42
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
ArduinoJson: change log
22
=======================
33

4+
HEAD
5+
----
6+
7+
* Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693)
8+
* Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu)
9+
410
v5.13.1
511
-------
612

src/ArduinoJson/Deserialization/JsonParser.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class JsonParser {
4444

4545
const char *parseString();
4646
bool parseAnythingTo(JsonVariant *destination);
47-
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
4847

4948
inline bool parseArrayTo(JsonVariant *destination);
5049
inline bool parseObjectTo(JsonVariant *destination);

src/ArduinoJson/Deserialization/JsonParserImpl.hpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,6 @@ template <typename TReader, typename TWriter>
2020
inline bool
2121
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
2222
JsonVariant *destination) {
23-
if (_nestingLimit == 0) return false;
24-
_nestingLimit--;
25-
bool success = parseAnythingToUnsafe(destination);
26-
_nestingLimit++;
27-
return success;
28-
}
29-
30-
template <typename TReader, typename TWriter>
31-
inline bool
32-
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
33-
JsonVariant *destination) {
3423
skipSpacesAndComments(_reader);
3524

3625
switch (_reader.current()) {
@@ -48,6 +37,9 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
4837
template <typename TReader, typename TWriter>
4938
inline ArduinoJson::JsonArray &
5039
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
40+
if (_nestingLimit == 0) return JsonArray::invalid();
41+
_nestingLimit--;
42+
5143
// Create an empty array
5244
JsonArray &array = _buffer->createArray();
5345

@@ -69,6 +61,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
6961

7062
SUCCESS_EMPTY_ARRAY:
7163
SUCCES_NON_EMPTY_ARRAY:
64+
_nestingLimit++;
7265
return array;
7366

7467
ERROR_INVALID_VALUE:
@@ -91,6 +84,9 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
9184
template <typename TReader, typename TWriter>
9285
inline ArduinoJson::JsonObject &
9386
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
87+
if (_nestingLimit == 0) return JsonObject::invalid();
88+
_nestingLimit--;
89+
9490
// Create an empty object
9591
JsonObject &object = _buffer->createObject();
9692

@@ -117,6 +113,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
117113

118114
SUCCESS_EMPTY_OBJECT:
119115
SUCCESS_NON_EMPTY_OBJECT:
116+
_nestingLimit++;
120117
return object;
121118

122119
ERROR_INVALID_KEY:

test/JsonBuffer/nestingLimit.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,62 @@
55
#include <ArduinoJson.h>
66
#include <catch.hpp>
77

8-
bool tryParseArray(const char *json, uint8_t nestingLimit) {
9-
DynamicJsonBuffer buffer;
10-
return buffer.parseArray(json, nestingLimit).success();
11-
}
12-
13-
bool tryParseObject(const char *json, uint8_t nestingLimit) {
14-
DynamicJsonBuffer buffer;
15-
return buffer.parseObject(json, nestingLimit).success();
16-
}
8+
#define SHOULD_WORK(expression) REQUIRE(true == expression.success());
9+
#define SHOULD_FAIL(expression) REQUIRE(false == expression.success());
1710

1811
TEST_CASE("JsonParser nestingLimit") {
19-
SECTION("ParseArrayWithNestingLimit0") {
20-
REQUIRE(true == tryParseArray("[]", 0));
21-
REQUIRE(false == tryParseArray("[[]]", 0));
22-
}
12+
DynamicJsonBuffer jb;
2313

24-
SECTION("ParseArrayWithNestingLimit1") {
25-
REQUIRE(true == tryParseArray("[[]]", 1));
26-
REQUIRE(false == tryParseArray("[[[]]]", 1));
27-
}
14+
SECTION("parseArray()") {
15+
SECTION("limit = 0") {
16+
SHOULD_FAIL(jb.parseArray("[]", 0));
17+
}
2818

29-
SECTION("ParseArrayWithNestingLimit2") {
30-
REQUIRE(true == tryParseArray("[[[]]]", 2));
31-
REQUIRE(false == tryParseArray("[[[[]]]]", 2));
32-
}
19+
SECTION("limit = 1") {
20+
SHOULD_WORK(jb.parseArray("[]", 1));
21+
SHOULD_FAIL(jb.parseArray("[[]]", 1));
22+
}
3323

34-
SECTION("ParseObjectWithNestingLimit0") {
35-
REQUIRE(true == tryParseObject("{}", 0));
36-
REQUIRE(false == tryParseObject("{\"key\":{}}", 0));
24+
SECTION("limit = 2") {
25+
SHOULD_WORK(jb.parseArray("[[]]", 2));
26+
SHOULD_FAIL(jb.parseArray("[[[]]]", 2));
27+
}
3728
}
3829

39-
SECTION("ParseObjectWithNestingLimit1") {
40-
REQUIRE(true == tryParseObject("{\"key\":{}}", 1));
41-
REQUIRE(false == tryParseObject("{\"key\":{\"key\":{}}}", 1));
30+
SECTION("parseObject()") {
31+
SECTION("limit = 0") {
32+
SHOULD_FAIL(jb.parseObject("{}", 0));
33+
}
34+
35+
SECTION("limit = 1") {
36+
SHOULD_WORK(jb.parseObject("{\"key\":42}", 1));
37+
SHOULD_FAIL(jb.parseObject("{\"key\":{\"key\":42}}", 1));
38+
}
39+
40+
SECTION("limit = 2") {
41+
SHOULD_WORK(jb.parseObject("{\"key\":{\"key\":42}}", 2));
42+
SHOULD_FAIL(jb.parseObject("{\"key\":{\"key\":{\"key\":42}}}", 2));
43+
}
4244
}
4345

44-
SECTION("ParseObjectWithNestingLimit2") {
45-
REQUIRE(true == tryParseObject("{\"key\":{\"key\":{}}}", 2));
46-
REQUIRE(false == tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2));
46+
SECTION("parse()") {
47+
SECTION("limit = 0") {
48+
SHOULD_WORK(jb.parse("\"toto\"", 0));
49+
SHOULD_WORK(jb.parse("123", 0));
50+
SHOULD_WORK(jb.parse("true", 0));
51+
SHOULD_FAIL(jb.parse("[]", 0));
52+
SHOULD_FAIL(jb.parse("{}", 0));
53+
SHOULD_FAIL(jb.parse("[\"toto\"]", 0));
54+
SHOULD_FAIL(jb.parse("{\"toto\":1}", 0));
55+
}
56+
57+
SECTION("limit = 1") {
58+
SHOULD_WORK(jb.parse("[\"toto\"]", 1));
59+
SHOULD_WORK(jb.parse("{\"toto\":1}", 1));
60+
SHOULD_FAIL(jb.parse("{\"toto\":{}}", 1));
61+
SHOULD_FAIL(jb.parse("{\"toto\":[]}", 1));
62+
SHOULD_FAIL(jb.parse("[[\"toto\"]]", 1));
63+
SHOULD_FAIL(jb.parse("[{\"toto\":1}]", 1));
64+
}
4765
}
4866
}

0 commit comments

Comments
 (0)
0