parser json BUGFIX parsing object key-value pair in lydjson_data_skip()
After a key-value pair was successfully parsed in lydjson_data_skip()
lyjson_ctx_next() parses the next key and returns LYJSON_OBJECT.
Add a missing check to see whether a nested object was actually parsed
or whether it was the next key.
Remove sublevel checks for LYJSON_OBJECT_EMPTY and LYJSON_ARRAY_EMPTY.
In the case of empty objects, jsonctx->depth doesn't change after calling
lyjson_ctx_next(), so sublevel is never increased.
This issue was found by OSS-Fuzz in lyd_parse_mem_json.
Signed-off-by: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
diff --git a/src/parser_json.c b/src/parser_json.c
index 095705b..e2ed9ae 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -287,12 +287,23 @@
/* skip after the content */
do {
+ uint32_t prev_depth = jsonctx->depth;
+
LY_CHECK_RET(lyjson_ctx_next(jsonctx, ¤t));
+
if (current == status) {
+ /* lyjson_ctx_next() can return LYSJON_OBJECT in two cases, either when
+ * a new object is encountered, or when it finishes parsing a value from a
+ * previous key-value pair. In the latter case the sublevel shouldn't increase.
+ */
+ if ((status == LYJSON_OBJECT) && (prev_depth == jsonctx->depth)) {
+ continue;
+ }
+
sublevels++;
- } else if ((status == LYJSON_OBJECT) && ((current == LYJSON_OBJECT_CLOSED) || (current == LYJSON_OBJECT_EMPTY))) {
+ } else if ((status == LYJSON_OBJECT) && (current == LYJSON_OBJECT_CLOSED)) {
sublevels--;
- } else if ((status == LYJSON_ARRAY) && ((current == LYJSON_ARRAY_CLOSED) || (current == LYJSON_ARRAY_EMPTY))) {
+ } else if ((status == LYJSON_ARRAY) && (current == LYJSON_ARRAY_CLOSED)) {
sublevels--;
}
} while (current != status + 1 || sublevels);
diff --git a/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_1 b/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_1
new file mode 100644
index 0000000..e411daa
--- /dev/null
+++ b/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_1
@@ -0,0 +1 @@
+{"types:cont":{"leaflt30,1,10,2]xxnt32":1,"types:uint":1,"types:uinis2":922337203685477}}
\ No newline at end of file
diff --git a/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_2 b/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_2
new file mode 100644
index 0000000..623be41
--- /dev/null
+++ b/tests/fuzz/corpus/lyd_parse_mem_json/pull1696_2
@@ -0,0 +1 @@
+{"types:cont":{"leaflt30,1,GGGGGGGGGGGGGGGGGGGGGGGGGGGGG10,2]xxnt32":1,"types:ui~t":1,"types:uinis2":922337203685477}}
\ No newline at end of file