Skip to content

Commit bd117f0

Browse files
committed
schema parsers BUGFIX convert default identityref/instance-identifier value into JSON format
default identityref and instance-identifier values defined in schemas uses imported modules as prefixes, but libyang internally uses JSON format with module names used as node's prefixes, so we have to convert the values on parsing and be prepared to convert values back when printing schema.
1 parent 9693540 commit bd117f0

6 files changed

Lines changed: 133 additions & 11 deletions

File tree

src/parser.c

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10071007
/*
10081008
* xml - optional for converting instance-identifier and identityref into JSON format
10091009
* tree - optional for resolving instance-identifiers and leafrefs
1010-
* leaf - optional for storing parsed data
1010+
* leaf - optional for storing parsed data, mandatory in case of dflt
10111011
*/
10121012
struct lys_type *
10131013
lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *xml, struct lyd_node *tree,
@@ -1021,6 +1021,8 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
10211021
struct lys_type_bit **bits = NULL;
10221022
struct lys_ident *ident;
10231023

1024+
assert(leaf || !dflt);
1025+
10241026
if (leaf) {
10251027
leaf->value_type = type->base;
10261028
}
@@ -1263,6 +1265,28 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
12631265
}
12641266
goto cleanup;
12651267
}
1268+
} else if (dflt) {
1269+
/* turn logging off */
1270+
hidden = *ly_vlog_hide_location();
1271+
ly_vlog_hide(1);
1272+
1273+
/* the value actually uses module's prefixes instead of the module names as in JSON format,
1274+
* we have to convert it */
1275+
value = transform_schema2json(leaf->schema->module, value);
1276+
if (!value) {
1277+
/* invalid identityref format or it was already transformed, so ignore the error here */
1278+
value = *value_;
1279+
/* erase error information */
1280+
ly_err_clean(1);
1281+
} else if (value == *value_) {
1282+
/* we have actually created the same expression (prefixes are the same as the module names)
1283+
* so we have just increased dictionary's refcount - fix it */
1284+
lydict_remove(type->parent->module->ctx, value);
1285+
}
1286+
/* turn logging back on */
1287+
if (!hidden) {
1288+
ly_vlog_hide(0);
1289+
}
12661290
}
12671291

12681292
ident = resolve_identref(type, value, (struct lyd_node*)leaf);
@@ -1273,10 +1297,15 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
12731297
leaf->value.ident = ident;
12741298
}
12751299

1276-
if (xml) {
1300+
if (value != *value_) {
12771301
/* update the changed value */
12781302
lydict_remove(type->parent->module->ctx, *value_);
12791303
*value_ = value;
1304+
1305+
/* we have to remember the conversion into JSON format to be able to print it in correct form */
1306+
if (dflt) {
1307+
type->parent->flags |= LYS_DFLTJSON;
1308+
}
12801309
}
12811310
break;
12821311

@@ -1302,6 +1331,28 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
13021331
}
13031332
goto cleanup;
13041333
}
1334+
} else if (dflt) {
1335+
/* turn logging off */
1336+
hidden = *ly_vlog_hide_location();
1337+
ly_vlog_hide(1);
1338+
1339+
/* the value actually uses module's prefixes instead of the module names as in JSON format,
1340+
* we have to convert it */
1341+
value = transform_schema2json(leaf->schema->module, value);
1342+
if (!value) {
1343+
/* invalid identityref format or it was already transformed, so ignore the error here */
1344+
value = *value_;
1345+
/* erase error information */
1346+
ly_err_clean(1);
1347+
} else if (value == *value_) {
1348+
/* we have actually created the same expression (prefixes are the same as the module names)
1349+
* so we have just increased dictionary's refcount - fix it */
1350+
lydict_remove(type->parent->module->ctx, value);
1351+
}
1352+
/* turn logging back on */
1353+
if (!hidden) {
1354+
ly_vlog_hide(0);
1355+
}
13051356
}
13061357
if (resolvable && tree && !resolve_instid(tree, value) && (ly_errno || type->info.inst.req)) {
13071358
if (leaf) {
@@ -1316,10 +1367,15 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
13161367
leaf->value_type |= LY_TYPE_INST_UNRES;
13171368
}
13181369

1319-
if (xml) {
1370+
if (value != *value_) {
13201371
/* update the changed value */
13211372
lydict_remove(type->parent->module->ctx, *value_);
13221373
*value_ = value;
1374+
1375+
/* we have to remember the conversion into JSON format to be able to print it in correct form */
1376+
if (dflt) {
1377+
type->parent->flags |= LYS_DFLTJSON;
1378+
}
13231379
}
13241380
break;
13251381

src/parser_yang.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,9 +2111,11 @@ yang_fill_deviate_default(struct ly_ctx *ctx, struct type_deviation *dev, char *
21112111
/* remove value */
21122112
lydict_remove(ctx, leaf->dflt);
21132113
leaf->dflt = NULL;
2114+
leaf->flags &= ~LYS_DFLTJSON;
21142115
} else { /* add (already checked) and replace */
21152116
/* remove value */
21162117
lydict_remove(ctx, leaf->dflt);
2118+
leaf->flags &= ~LYS_DFLTJSON;
21172119

21182120
/* set new value */
21192121
leaf->dflt = lydict_insert(ctx, value, u);
@@ -2154,6 +2156,7 @@ yang_fill_deviate_default(struct ly_ctx *ctx, struct type_deviation *dev, char *
21542156

21552157
/* remember to check it later (it may not fit now, but the type can be deviated too) */
21562158
ly_set_add(dev->dflt_check, dev->target, 0);
2159+
llist->flags &= ~LYS_DFLTJSON;
21572160
}
21582161
}
21592162

src/parser_yin.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2303,14 +2303,16 @@ fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys
23032303
/* remove value */
23042304
lydict_remove(ctx, leaf->dflt);
23052305
leaf->dflt = NULL;
2306+
leaf->flags &= ~LYS_DFLTJSON;
23062307
} else { /* add (already checked) and replace */
23072308
/* remove value */
23082309
lydict_remove(ctx, leaf->dflt);
2310+
leaf->flags &= ~LYS_DFLTJSON;
23092311

23102312
/* set new value */
23112313
leaf->dflt = lydict_insert(ctx, value, u);
23122314

2313-
/* remember to check it later (it may not fit now, but the type can be deviated too) */
2315+
/* remember to check it later (it may not fit now, because the type can be deviated too) */
23142316
ly_set_add(dflt_check, dev_target, 0);
23152317
}
23162318
} else { /* LYS_LEAFLIST */
@@ -2346,6 +2348,7 @@ fill_yin_deviation(struct lys_module *module, struct lyxml_elem *yin, struct lys
23462348

23472349
/* remember to check it later (it may not fit now, but the type can be deviated too) */
23482350
ly_set_add(dflt_check, dev_target, 0);
2351+
leaf->flags &= ~LYS_DFLTJSON;
23492352
}
23502353
}
23512354
}

src/printer_yang.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -688,14 +688,23 @@ yang_print_typedef(struct lyout *out, int level, const struct lys_module *module
688688
{
689689
ly_print(out, "%*stypedef %s {\n", LEVEL, INDENT, tpdf->name);
690690
level++;
691+
const char *dflt;
691692

692693
yang_print_snode_common(out, level, (struct lys_node *)tpdf, NULL);
693694
yang_print_type(out, level, module, &tpdf->type);
694695
if (tpdf->units != NULL) {
695696
ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, tpdf->units);
696697
}
697698
if (tpdf->dflt != NULL) {
698-
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, tpdf->dflt);
699+
if (tpdf->flags & LYS_DFLTJSON) {
700+
dflt = transform_json2schema(module, tpdf->dflt);
701+
} else {
702+
dflt = tpdf->dflt;
703+
}
704+
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, dflt);
705+
if (tpdf->flags & LYS_DFLTJSON) {
706+
lydict_remove(module->ctx, dflt);
707+
}
699708
}
700709

701710
level--;
@@ -857,6 +866,7 @@ yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
857866
{
858867
int i;
859868
struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
869+
const char *dflt;
860870

861871
ly_print(out, "%*sleaf %s {\n", LEVEL, INDENT, node->name);
862872

@@ -877,7 +887,15 @@ yang_print_leaf(struct lyout *out, int level, const struct lys_node *node)
877887
ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, leaf->units);
878888
}
879889
if (leaf->dflt) {
880-
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, leaf->dflt);
890+
if (leaf->flags & LYS_DFLTJSON) {
891+
dflt = transform_json2schema(node->module, leaf->dflt);
892+
} else {
893+
dflt = leaf->dflt;
894+
}
895+
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, dflt);
896+
if (leaf->flags & LYS_DFLTJSON) {
897+
lydict_remove(node->module->ctx, dflt);
898+
}
881899
}
882900
level--;
883901

@@ -915,6 +933,7 @@ yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
915933
{
916934
int i;
917935
struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
936+
const char *dflt;
918937

919938
ly_print(out, "%*sleaf-list %s {\n", LEVEL, INDENT, node->name);
920939

@@ -932,7 +951,15 @@ yang_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
932951
yang_print_snode_common2(out, level, node, NULL);
933952
yang_print_type(out, level, node->module, &llist->type);
934953
for (i = 0; i < llist->dflt_size; ++i) {
935-
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, llist->dflt[i]);
954+
if (llist->flags & LYS_DFLTJSON) {
955+
dflt = transform_json2schema(node->module, llist->dflt[i]);
956+
} else {
957+
dflt = llist->dflt[i];
958+
}
959+
ly_print(out, "%*sdefault \"%s\";\n", LEVEL, INDENT, dflt);
960+
if (llist->flags & LYS_DFLTJSON) {
961+
lydict_remove(node->module->ctx, dflt);
962+
}
936963
}
937964
if (llist->units != NULL) {
938965
ly_print(out, "%*sunits \"%s\";\n", LEVEL, INDENT, llist->units);

src/printer_yin.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ static void
706706
yin_print_typedef(struct lyout *out, int level, const struct lys_module *module, const struct lys_tpdf *tpdf)
707707
{
708708
yin_print_open(out, level, "typedef", "name", tpdf->name, 0);
709+
const char *dflt;
709710

710711
level++;
711712
yin_print_snode_common(out, level, (struct lys_node *)tpdf);
@@ -714,7 +715,15 @@ yin_print_typedef(struct lyout *out, int level, const struct lys_module *module,
714715
yin_print_open(out, level, "units", "name", tpdf->units, 1);
715716
}
716717
if (tpdf->dflt) {
717-
yin_print_open(out, level, "default", "value", tpdf->dflt, 1);
718+
if (tpdf->flags & LYS_DFLTJSON) {
719+
dflt = transform_json2schema(module, tpdf->dflt);
720+
} else {
721+
dflt = tpdf->dflt;
722+
}
723+
yin_print_open(out, level, "default", "value", dflt, 1);
724+
if (tpdf->flags & LYS_DFLTJSON) {
725+
lydict_remove(module->ctx, dflt);
726+
}
718727
}
719728
level--;
720729

@@ -874,6 +883,7 @@ yin_print_leaf(struct lyout *out, int level, const struct lys_node *node)
874883
{
875884
int i;
876885
struct lys_node_leaf *leaf = (struct lys_node_leaf *)node;
886+
const char *dflt;
877887

878888
yin_print_open(out, level, "leaf", "name", node->name, 0);
879889

@@ -894,7 +904,15 @@ yin_print_leaf(struct lyout *out, int level, const struct lys_node *node)
894904
yin_print_open(out, level, "units", "name", leaf->units, 1);
895905
}
896906
if (leaf->dflt) {
897-
yin_print_open(out, level, "default", "value", leaf->dflt, 1);
907+
if (leaf->flags & LYS_DFLTJSON) {
908+
dflt = transform_json2schema(node->module, leaf->dflt);
909+
} else {
910+
dflt = leaf->dflt;
911+
}
912+
yin_print_open(out, level, "default", "value", dflt, 1);
913+
if (leaf->flags & LYS_DFLTJSON) {
914+
lydict_remove(node->module->ctx, dflt);
915+
}
898916
}
899917
level--;
900918

@@ -937,6 +955,7 @@ yin_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
937955
{
938956
int i;
939957
struct lys_node_leaflist *llist = (struct lys_node_leaflist *)node;
958+
const char *dflt;
940959

941960
yin_print_open(out, level, "leaf-list", "name", node->name, 0);
942961

@@ -957,7 +976,15 @@ yin_print_leaflist(struct lyout *out, int level, const struct lys_node *node)
957976
yin_print_open(out, level, "units", "name", llist->units, 1);
958977
}
959978
for (i = 0; i < llist->dflt_size; i++) {
960-
yin_print_open(out, level, "default", "value", llist->dflt[i], 1);
979+
if (llist->flags & LYS_DFLTJSON) {
980+
dflt = transform_json2schema(node->module, llist->dflt[i]);
981+
} else {
982+
dflt = llist->dflt[i];
983+
}
984+
yin_print_open(out, level, "default", "value", dflt, 1);
985+
if (llist->flags & LYS_DFLTJSON) {
986+
lydict_remove(node->module->ctx, dflt);
987+
}
961988
}
962989
if (llist->min > 0) {
963990
yin_print_unsigned(out, level, "min-elements", "value", llist->min);

src/tree_schema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,8 @@ struct lys_iffeature {
639639
* LYS_FENABLED | | | | | | | | | | | | | | |x| | | |
640640
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
641641
* 10 LYS_VALID_DEP |x|x|x|x|x|x|x|x|x|x|x| |x|x| | | | |
642+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
643+
* 11 LYS_DFLTJSON | | |x|x| | | | | | | | | | | |x| | |
642644
* --------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
643645
* @{
644646
*/
@@ -670,6 +672,10 @@ struct lys_iffeature {
670672
#define LYS_VALID_DEP 0x200 /**< flag marking nodes, whose validation (when, must expressions or leafrefs)
671673
depends on nodes outside their subtree (applicable only to RPCs,
672674
notifications, and actions) */
675+
#define LYS_DFLTJSON 0x400 /**< default value (in ::lys_node_leaf, ::lys_node_leaflist, :lys_tpdf) was
676+
converted into JSON format, since it contains identityref value which is
677+
being used in JSON format (instead of module prefixes, we use the module
678+
names) */
673679
/**
674680
* @}
675681
*/
@@ -1455,7 +1461,7 @@ struct lys_tpdf {
14551461
const char *name; /**< name of the newly defined type (mandatory) */
14561462
const char *dsc; /**< description statement (optional) */
14571463
const char *ref; /**< reference statement (optional) */
1458-
uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_ values (or 0) are allowed */
1464+
uint16_t flags; /**< [schema node flags](@ref snodeflags) - only LYS_STATUS_ and LYS_DFLTJSON values (or 0) are allowed */
14591465
struct lys_module *module; /**< pointer to the module where the data type is defined (mandatory),
14601466
NULL in case of built-in typedefs */
14611467

0 commit comments

Comments
 (0)