From cbbae4291a5cd2bf5fe662cbd8f5a00a1bd7488e Mon Sep 17 00:00:00 2001 From: steweg Date: Mon, 22 Apr 2024 11:38:25 +0200 Subject: [PATCH] parser json BUGFIX printing opaque nodes as containers (#2230) In case there are empty containers in JSON output, they were not stored as such and term nodes were incorrectly printed. --- src/parser_json.c | 1 + src/printer_json.c | 3 +- src/tree_data.h | 5 +-- tests/utests/CMakeLists.txt | 1 + tests/utests/data/test_printer_json.c | 52 +++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 tests/utests/data/test_printer_json.c diff --git a/src/parser_json.c b/src/parser_json.c index d7f2fa57d..55f0ed9fa 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1085,6 +1085,7 @@ lydjson_parse_opaq(struct lyd_json_ctx *lydctx, const char *name, size_t name_le } if (*status_p == LYJSON_OBJECT) { + ((struct lyd_node_opaq *)*node_p)->hints |= LYD_NODEHINT_CONTAINER; /* process children */ do { LY_CHECK_GOTO(ret = lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL), cleanup); diff --git a/src/printer_json.c b/src/printer_json.c index 29ca0e7c5..df24e3aee 100644 --- a/src/printer_json.c +++ b/src/printer_json.c @@ -582,7 +582,6 @@ json_print_any_content(struct jsonpr_ctx *pctx, struct lyd_node_any *any) if ((any->schema->nodetype == LYS_ANYDATA) && (any->value_type != LYD_ANYDATA_DATATREE)) { LOGINT_RET(pctx->ctx); } - if (any->value_type == LYD_ANYDATA_LYB) { uint32_t parser_options = LYD_PARSE_ONLY | LYD_PARSE_OPAQ | LYD_PARSE_STRICT; @@ -942,7 +941,7 @@ json_print_opaq(struct jsonpr_ctx *pctx, const struct lyd_node_opaq *node) } else if (node->hints & LYD_NODEHINT_LEAFLIST) { ly_print_(pctx->out, ",%s%*s", DO_FORMAT ? "\n" : "", INDENT); } - if (node->child || (node->hints & LYD_NODEHINT_LIST)) { + if (node->child || (node->hints & LYD_NODEHINT_LIST) || (node->hints & LYD_NODEHINT_CONTAINER)) { LY_CHECK_RET(json_print_inner(pctx, &node->node)); LEVEL_PRINTED; } else { diff --git a/src/tree_data.h b/src/tree_data.h index ff25b8b18..f920c20f2 100644 --- a/src/tree_data.h +++ b/src/tree_data.h @@ -955,6 +955,7 @@ struct lyd_node_any { */ #define LYD_NODEHINT_LIST 0x0080 /**< node is allowed to be a list instance */ #define LYD_NODEHINT_LEAFLIST 0x0100 /**< node is allowed to be a leaf-list instance */ +#define LYD_NODEHINT_CONTAINER 0x0200 /**< node is allowed to be a container instance */ /** * @} lydnodehints */ @@ -969,11 +970,11 @@ struct lyd_node_any { * Any information about value and node types encoded in the format is hinted by these values. * It combines [value hints](@ref lydvalhints) and [node hints](@ref lydnodehints). */ -#define LYD_HINT_DATA 0x01F3 /**< special node/value hint to be used for generic data node/value (for cases when +#define LYD_HINT_DATA 0x03F3 /**< special node/value hint to be used for generic data node/value (for cases when there is no encoding or it does not provide any additional information about a node/value type); do not combine with specific [value hints](@ref lydvalhints) or [node hints](@ref lydnodehints). */ -#define LYD_HINT_SCHEMA 0x01FF /**< special node/value hint to be used for generic schema node/value(for cases when +#define LYD_HINT_SCHEMA 0x03FF /**< special node/value hint to be used for generic schema node/value(for cases when there is no encoding or it does not provide any additional information about a node/value type); do not combine with specific [value hints](@ref lydvalhints) or [node hints](@ref lydnodehints). */ diff --git a/tests/utests/CMakeLists.txt b/tests/utests/CMakeLists.txt index 648098a5b..46558e8ca 100644 --- a/tests/utests/CMakeLists.txt +++ b/tests/utests/CMakeLists.txt @@ -65,6 +65,7 @@ ly_add_utest(NAME tree_data_sorted SOURCES data/test_tree_data_sorted.c) ly_add_utest(NAME new SOURCES data/test_new.c) ly_add_utest(NAME parser_xml SOURCES data/test_parser_xml.c) ly_add_utest(NAME printer_xml SOURCES data/test_printer_xml.c) +ly_add_utest(NAME printer_json SOURCES data/test_printer_json.c) ly_add_utest(NAME parser_json SOURCES data/test_parser_json.c) ly_add_utest(NAME lyb SOURCES data/test_lyb.c) ly_add_utest(NAME validation SOURCES data/test_validation.c) diff --git a/tests/utests/data/test_printer_json.c b/tests/utests/data/test_printer_json.c new file mode 100644 index 000000000..85ace73d1 --- /dev/null +++ b/tests/utests/data/test_printer_json.c @@ -0,0 +1,52 @@ +/* + * @file test_printer_json.c + * @author: Radek Krejci + * @brief unit tests for functions from printer_yang.c + * + * Copyright (c) 2019-2020 CESNET, z.s.p.o. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ +#define _UTEST_MAIN_ +#include "utests.h" + +static int +setup(void **state) +{ + const char *schema1 = "module schema1 {namespace urn:tests:schema1;prefix schema1;yang-version 1.1;" + "revision 2014-05-08;" + "anydata data;" + "}"; + + UTEST_SETUP; + UTEST_ADD_MODULE(schema1, LYS_IN_YANG, NULL, NULL); + return 0; +} + +static void +test_container_presence(void **state) +{ + struct lyd_node *tree; + char *buffer = NULL; + const char *data = "{\"schema1:data\":{\"cont1\":{}}}"; + + CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); + assert_int_equal(LY_SUCCESS, lyd_print_mem(&buffer, tree, LYD_JSON, LYD_PRINT_SHRINK)); + CHECK_STRING(buffer, data); + free(buffer); + lyd_free_all(tree); +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + UTEST(test_container_presence, setup), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}