Skip to content

Commit f31b404

Browse files
berendomrfuchs
andauthored
Backport JSON parser improvement (#81)
* json: Skip unknown fields on parsing Skip child objects and arrays that are not specified in the given object descriptor when parsing a JSON input string. This patch adds support for extra child arrays which previously were not supported by the parser as opposed to additional child objects. Fixes zephyrproject-rtos#47988 Signed-off-by: Markus Fuchs <[email protected]> * tests: lib: json: Add tests for parsing inputs with extra fields Add tests for both extra objects and extra arrays nested in JSON objects. Fields in extra nested objects should be ignored and also not manipulate subsequent fields with the same name. Signed-off-by: Markus Fuchs <[email protected]> --------- Signed-off-by: Markus Fuchs <[email protected]> Co-authored-by: Markus Fuchs <[email protected]>
1 parent 414d8fd commit f31b404

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

lib/os/json.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,33 @@ static int arr_next(struct json_obj *json, struct token *value)
388388
return element_token(value->type);
389389
}
390390

391+
static int skip_field(struct json_obj *obj, struct json_obj_key_value *kv)
392+
{
393+
int field_count = 1;
394+
395+
if (kv->value.type == JSON_TOK_OBJECT_START ||
396+
kv->value.type == JSON_TOK_LIST_START) {
397+
while (field_count > 0 && lexer_next(&obj->lexer, &kv->value)) {
398+
switch (kv->value.type) {
399+
case JSON_TOK_OBJECT_START:
400+
case JSON_TOK_LIST_START:
401+
field_count++;
402+
break;
403+
case JSON_TOK_OBJECT_END:
404+
case JSON_TOK_LIST_END:
405+
field_count--;
406+
break;
407+
case JSON_TOK_ERROR:
408+
return -EINVAL;
409+
default:
410+
break;
411+
}
412+
}
413+
}
414+
415+
return 0;
416+
}
417+
391418
static int decode_num(const struct token *token, int32_t *num)
392419
{
393420
/* FIXME: strtod() is not available in newlib/minimal libc,
@@ -585,6 +612,14 @@ static int obj_parse(struct json_obj *obj, const struct json_obj_descr *descr,
585612
decoded_fields |= 1<<i;
586613
break;
587614
}
615+
616+
/* Skip field, if no descriptor was found */
617+
if (i >= descr_len) {
618+
ret = skip_field(obj, &kv);
619+
if (ret < 0) {
620+
return ret;
621+
}
622+
}
588623
}
589624

590625
return -EINVAL;

tests/lib/json/src/main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,11 @@ static void test_json_decoding(void)
164164
"\"some_nested_struct\":{ "
165165
"\"nested_int\":-1234,\n\n"
166166
"\"nested_bool\":false,\t"
167-
"\"nested_string\":\"this should be escaped: \\t\"},"
168-
"\"some_array\":[11,22, 33,\t45,\n299]"
167+
"\"nested_string\":\"this should be escaped: \\t\","
168+
"\"extra_nested_array\":[0,-1]},"
169+
"\"extra_struct\":{\"nested_bool\":false},"
170+
"\"extra_bool\":true,"
171+
"\"some_array\":[11,22, 33,\t45,\n299],"
169172
"\"another_b!@l\":true,"
170173
"\"if\":false,"
171174
"\"another-array\":[2,3,5,7],"

0 commit comments

Comments
 (0)