Skip to content

Commit ca25b01

Browse files
committed
printer json BUGFIX use WD module for JSON default metadata
For JSON, this m odule should be used but for XML a namespace of a different module must be used. Refs #2490
1 parent c1e1f8a commit ca25b01

File tree

5 files changed

+85
-31
lines changed

5 files changed

+85
-31
lines changed

src/parser_common.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ lyd_parser_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct
286286
const struct lysc_ext_instance *ext)
287287
{
288288
struct lyd_meta *meta2, *prev_meta = NULL, *next_meta = NULL;
289+
const struct lys_module *mod;
289290

290291
if (lydctx->parse_opts & LYD_PARSE_NO_NEW) {
291292
node->flags &= ~LYD_NEW;
@@ -303,8 +304,9 @@ lyd_parser_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct
303304
}
304305

305306
LY_LIST_FOR(*meta, meta2) {
306-
if (!strcmp(meta2->name, "default") && !strcmp(meta2->annotation->module->name, "default") &&
307-
meta2->value.boolean) {
307+
mod = meta2->annotation->module;
308+
if (!strcmp(meta2->name, "default") &&
309+
(!strcmp(mod->name, "default") || !strcmp(mod->name, "ietf-netconf-with-defaults")) && meta2->value.boolean) {
308310
/* node is default according to the metadata */
309311
node->flags |= LYD_DEFAULT;
310312

src/printer_json.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -540,26 +540,25 @@ node_has_printable_meta(const struct lyd_node *node)
540540
static LY_ERR
541541
json_print_attributes(struct jsonpr_ctx *pctx, const struct lyd_node *node, ly_bool inner)
542542
{
543-
const struct lys_module *df_mod = NULL;
543+
const struct lys_module *wd_mod = NULL;
544544

545545
if (node->schema && (node->schema->nodetype != LYS_CONTAINER) && (((node->flags & LYD_DEFAULT) &&
546546
(pctx->options & (LYD_PRINT_WD_ALL_TAG | LYD_PRINT_WD_IMPL_TAG))) ||
547547
((pctx->options & LYD_PRINT_WD_ALL_TAG) && lyd_is_default(node)))) {
548-
/* we have implicit OR explicit default node, print only if we have with-defaults module */
549-
if (ly_ctx_get_module_implemented(LYD_CTX(node), "ietf-netconf-with-defaults")) {
550-
df_mod = ly_ctx_get_module_implemented(LYD_CTX(node), "default");
551-
}
548+
/* we have implicit OR explicit default node, print only if we have with-defaults module
549+
* (module name according to https://datatracker.ietf.org/doc/html/rfc8040#page-60) */
550+
wd_mod = ly_ctx_get_module_implemented(LYD_CTX(node), "ietf-netconf-with-defaults");
552551
}
553552

554-
if (node->schema && (df_mod || node_has_printable_meta(node))) {
553+
if (node->schema && (wd_mod || node_has_printable_meta(node))) {
555554
if (inner) {
556555
LY_CHECK_RET(json_print_member2(pctx, node->parent, LY_VALUE_JSON, NULL, 1));
557556
} else {
558557
LY_CHECK_RET(json_print_member(pctx, node, NULL, 1));
559558
}
560559
ly_print_(pctx->out, "{%s", (DO_FORMAT ? "\n" : ""));
561560
LEVEL_INC;
562-
LY_CHECK_RET(json_print_metadata(pctx, node, df_mod));
561+
LY_CHECK_RET(json_print_metadata(pctx, node, wd_mod));
563562
LEVEL_DEC;
564563
ly_print_(pctx->out, "%s%*s}", DO_FORMAT ? "\n" : "", INDENT);
565564
LEVEL_PRINTED;
@@ -832,7 +831,7 @@ json_print_array_is_last_inst(struct jsonpr_ctx *pctx, const struct lyd_node *no
832831
static LY_ERR
833832
json_print_leaf_list(struct jsonpr_ctx *pctx, const struct lyd_node *node)
834833
{
835-
const struct lys_module *df_mod = NULL;
834+
const struct lys_module *wd_mod = NULL;
836835

837836
if (!is_open_array(pctx, node)) {
838837
LY_CHECK_RET(json_print_member(pctx, node, NULL, 0));
@@ -856,11 +855,9 @@ json_print_leaf_list(struct jsonpr_ctx *pctx, const struct lyd_node *node)
856855
if (((node->flags & LYD_DEFAULT) && (pctx->options & (LYD_PRINT_WD_ALL_TAG | LYD_PRINT_WD_IMPL_TAG))) ||
857856
((pctx->options & LYD_PRINT_WD_ALL_TAG) && lyd_is_default(node))) {
858857
/* we have implicit OR explicit default node, print only if we have with-defaults module */
859-
if (ly_ctx_get_module_implemented(LYD_CTX(node), "ietf-netconf-with-defaults")) {
860-
df_mod = ly_ctx_get_module_implemented(LYD_CTX(node), "default");
861-
}
858+
wd_mod = ly_ctx_get_module_implemented(LYD_CTX(node), "ietf-netconf-with-defaults");
862859
}
863-
if (df_mod || node_has_printable_meta(node)) {
860+
if (wd_mod || node_has_printable_meta(node)) {
864861
/* we will be printing metadata for these siblings */
865862
pctx->first_leaflist = node;
866863
}
@@ -913,16 +910,14 @@ static LY_ERR
913910
json_print_meta_attr_leaflist(struct jsonpr_ctx *pctx)
914911
{
915912
const struct lyd_node *prev, *node, *iter;
916-
const struct lys_module *df_mod = NULL, *iter_dfmod;
913+
const struct lys_module *wd_mod = NULL, *iter_wdmod;
917914
const struct lyd_node_opaq *opaq = NULL;
918915

919916
assert(pctx->first_leaflist);
920917

921918
if (pctx->options & (LYD_PRINT_WD_ALL_TAG | LYD_PRINT_WD_IMPL_TAG)) {
922919
/* we have implicit OR explicit default node, print only if we have with-defaults module */
923-
if (ly_ctx_get_module_implemented(pctx->ctx, "ietf-netconf-with-defaults")) {
924-
df_mod = ly_ctx_get_module_implemented(pctx->ctx, "default");
925-
}
920+
wd_mod = ly_ctx_get_module_implemented(pctx->ctx, "ietf-netconf-with-defaults");
926921
}
927922

928923
/* node is the first instance of the leaf-list */
@@ -942,16 +937,16 @@ json_print_meta_attr_leaflist(struct jsonpr_ctx *pctx)
942937
LY_LIST_FOR(node, iter) {
943938
PRINT_COMMA;
944939
if (iter->schema && ((iter->flags & LYD_DEFAULT) || ((pctx->options & LYD_PRINT_WD_ALL_TAG) && lyd_is_default(iter)))) {
945-
iter_dfmod = df_mod;
940+
iter_wdmod = wd_mod;
946941
} else {
947-
iter_dfmod = NULL;
942+
iter_wdmod = NULL;
948943
}
949-
if ((iter->schema && (node_has_printable_meta(iter) || iter_dfmod)) || (opaq && opaq->attr)) {
944+
if ((iter->schema && (node_has_printable_meta(iter) || iter_wdmod)) || (opaq && opaq->attr)) {
950945
ly_print_(pctx->out, "%*s%s", INDENT, DO_FORMAT ? "{\n" : "{");
951946
LEVEL_INC;
952947

953948
if (iter->schema) {
954-
LY_CHECK_RET(json_print_metadata(pctx, iter, iter_dfmod));
949+
LY_CHECK_RET(json_print_metadata(pctx, iter, iter_wdmod));
955950
} else {
956951
LY_CHECK_RET(json_print_attribute(pctx, (struct lyd_node_opaq *)iter));
957952
}

src/printer_lyb.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -843,22 +843,20 @@ static LY_ERR
843843
lyb_print_metadata(const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
844844
{
845845
uint32_t count = 0;
846-
const struct lys_module *df_mod = NULL;
846+
const struct lys_module *wd_mod = NULL;
847847
struct lyd_meta *iter;
848848

849849
/* with-defaults */
850850
if (node->schema->nodetype & LYD_NODE_TERM) {
851851
if (((node->flags & LYD_DEFAULT) && (lybctx->print_options & (LYD_PRINT_WD_ALL_TAG | LYD_PRINT_WD_IMPL_TAG))) ||
852852
((lybctx->print_options & LYD_PRINT_WD_ALL_TAG) && lyd_is_default(node))) {
853853
/* we have implicit OR explicit default node, print attribute only if context include with-defaults schema */
854-
if (ly_ctx_get_module_latest(LYD_CTX(node), "ietf-netconf-with-defaults")) {
855-
df_mod = ly_ctx_get_module_latest(LYD_CTX(node), "default");
856-
}
854+
wd_mod = ly_ctx_get_module_latest(LYD_CTX(node), "ietf-netconf-with-defaults");
857855
}
858856
}
859857

860858
/* count metadata */
861-
if (df_mod) {
859+
if (wd_mod) {
862860
++count;
863861
}
864862
LY_LIST_FOR(node->meta, iter) {
@@ -876,12 +874,12 @@ lyb_print_metadata(const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
876874
/* write the number of metadata */
877875
LY_CHECK_RET(lyb_write_count(count, lybctx->print_ctx));
878876

879-
if (df_mod) {
877+
if (wd_mod) {
880878
/* write the "default" metadata */
881879
if (lybctx->print_ctx->shrink) {
882-
LY_CHECK_RET(lyb_print_module_idx(df_mod, lybctx->print_ctx));
880+
LY_CHECK_RET(lyb_print_module_idx(wd_mod, lybctx->print_ctx));
883881
} else {
884-
LY_CHECK_RET(lyb_print_module(df_mod, lybctx->print_ctx));
882+
LY_CHECK_RET(lyb_print_module(wd_mod, lybctx->print_ctx));
885883
}
886884
LY_CHECK_RET(lyb_write_string("default", 0, lybctx->print_ctx));
887885
LY_CHECK_RET(lyb_write_string("true", 0, lybctx->print_ctx));

src/tree_schema.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,63 @@ lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod)
21312131
return LY_SUCCESS;
21322132
}
21332133

2134+
/**
2135+
* @brief Add ietf-netconf-with-defaults "default" metadata to the parsed module.
2136+
*
2137+
* @param[in] pctx Parse context.
2138+
* @param[in] mod Parsed module to add to.
2139+
* @return LY_SUCCESS on success.
2140+
* @return LY_ERR on error.
2141+
*/
2142+
static LY_ERR
2143+
lysp_add_internal_ietf_netconf_with_defaults(struct lysp_ctx *pctx, struct lysp_module *mod)
2144+
{
2145+
struct lysp_ext_instance *extp, *prev_exts = mod->exts;
2146+
struct lysp_stmt *stmt;
2147+
struct lysp_import *imp;
2148+
uint32_t idx;
2149+
2150+
/* add new extension instance */
2151+
LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
2152+
2153+
/* fill in the extension instance fields */
2154+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
2155+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "default", 0, &extp->argument));
2156+
extp->format = LY_VALUE_SCHEMA;
2157+
extp->prefix_data = mod;
2158+
extp->parent = mod;
2159+
extp->parent_stmt = LY_STMT_MODULE;
2160+
extp->flags = LYS_INTERNAL;
2161+
2162+
extp->child = stmt = calloc(1, sizeof *extp->child);
2163+
LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
2164+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
2165+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "boolean", 0, &stmt->arg));
2166+
stmt->format = LY_VALUE_SCHEMA;
2167+
stmt->prefix_data = mod;
2168+
stmt->kw = LY_STMT_TYPE;
2169+
2170+
if (!prev_exts) {
2171+
/* first extension instances */
2172+
assert(pctx->main_ctx == pctx);
2173+
LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL));
2174+
} else {
2175+
/* replace previously stored extension instances */
2176+
if (!ly_set_contains(&pctx->ext_inst, prev_exts, &idx)) {
2177+
LOGINT_RET(mod->mod->ctx);
2178+
}
2179+
pctx->ext_inst.objs[idx] = mod->exts;
2180+
}
2181+
2182+
/* create new import for the used prefix */
2183+
LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
2184+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
2185+
LY_CHECK_RET(lysdict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
2186+
imp->flags = LYS_INTERNAL;
2187+
2188+
return LY_SUCCESS;
2189+
}
2190+
21342191
/**
21352192
* @brief Define a new internal 'lyds_tree' value for metadata.
21362193
*
@@ -2366,6 +2423,8 @@ lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const st
23662423
/* add internal data in case specific modules were parsed */
23672424
if (!strcmp(mod->name, "ietf-netconf")) {
23682425
LY_CHECK_GOTO(rc = lysp_add_internal_ietf_netconf(pctx, mod->parsed), cleanup);
2426+
} else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
2427+
LY_CHECK_GOTO(rc = lysp_add_internal_ietf_netconf_with_defaults(pctx, mod->parsed), cleanup);
23692428
} else if (!strcmp(mod->name, "yang")) {
23702429
LY_CHECK_GOTO(rc = lysp_add_internal_yang(pctx, mod->parsed), cleanup);
23712430
}

tests/utests/data/test_parser_json.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ test_leaf(void **state)
167167
lyd_free_all(tree);
168168

169169
/* parse foo2 but make it implicit */
170-
data = "{\"a:foo2\":\"default-val\",\"@a:foo2\":{\"default:default\":true}}";
170+
data = "{\"a:foo2\":\"default-val\",\"@a:foo2\":{\"ietf-netconf-with-defaults:default\":true}}";
171171
CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
172172
assert_non_null(tree);
173173
tree = tree->next;

0 commit comments

Comments
 (0)