data validation CHANGE unify handling of leafrefs in get/edit data
validation function were not reflecting unresolvable leafrefs in
the get/get-config/edit-config data trees. In case the data tree
was created by libyang functions (not parsed from a file), the
leafrefs were unresolved with no information about it (missing
LY_TYPE_LEAFREF_UNRES flag and no parsed value).
diff --git a/src/parser.c b/src/parser.c
index 392f8e3..c36134e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -845,8 +845,8 @@
*
* resolve - whether resolve identityrefs and leafrefs (which must be in JSON form)
*/
-static int
-lyp_parse_value_(struct lyd_node_leaf_list *node, struct lys_type *stype, int resolve)
+int
+lyp_parse_value_type(struct lyd_node_leaf_list *node, struct lys_type *stype, int resolve)
{
#define DECSIZE 21
struct lys_type *type;
@@ -1229,7 +1229,7 @@
}
}
- if (!lyp_parse_value_(leaf, type, resolve)) {
+ if (!lyp_parse_value_type(leaf, type, resolve)) {
/* success, erase set ly_errno and ly_vecode */
ly_errno = LY_SUCCESS;
ly_vecode = LYVE_SUCCESS;
@@ -1255,8 +1255,7 @@
}
} else {
memset(&leaf->value, 0, sizeof leaf->value);
- if (lyp_parse_value_(leaf, stype, resolve)) {
- ly_errno = LY_EVALID;
+ if (lyp_parse_value_type(leaf, stype, resolve)) {
return EXIT_FAILURE;
}
}
diff --git a/src/parser.h b/src/parser.h
index af336d1..de1e60e 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -62,6 +62,7 @@
struct lys_type *lyp_get_next_union_type(struct lys_type *type, struct lys_type *prev_type, int *found);
int lyp_parse_value(struct lyd_node_leaf_list *leaf, struct lyxml_elem *xml, int resolve);
+int lyp_parse_value_type(struct lyd_node_leaf_list *node, struct lys_type *stype, int resolve);
int lyp_check_length_range(const char *expr, struct lys_type *type);
diff --git a/src/validation.c b/src/validation.c
index 047f6d4..d8c6803 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -52,6 +52,7 @@
lyv_data_context(const struct lyd_node *node, int options, struct unres_data *unres)
{
const struct lys_node *siter = NULL;
+ struct lyd_node_leaf_list *leaf = (struct lyd_node_leaf_list *)node;
assert(node);
assert(unres);
@@ -63,20 +64,26 @@
}
/* check leafref/instance-identifier */
- if ((node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) &&
- !(options & (LYD_OPT_EDIT | LYD_OPT_GET | LYD_OPT_GETCONFIG))) {
- /* remove possible unres flags from type */
- ((struct lyd_node_leaf_list *)node)->value_type &= LY_DATA_TYPE_MASK;
-
- /* if leafref or instance-identifier, store the node for later resolving */
- if (((struct lyd_node_leaf_list *)node)->value_type == LY_TYPE_LEAFREF &&
- !((struct lyd_node_leaf_list *)node)->value.leafref) {
- if (unres_data_add(unres, (struct lyd_node *)node, UNRES_LEAFREF)) {
- return EXIT_FAILURE;
+ if (node->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
+ if (options & (LYD_OPT_EDIT | LYD_OPT_GET | LYD_OPT_GETCONFIG)) {
+ /* if leafref or instance-identifier, parse the value according to the
+ * target's type, because the target leaf does not need to be present */
+ if (leaf->value_type == LY_TYPE_LEAFREF || leaf->value_type == LY_TYPE_INST) {
+ memset(&leaf->value, 0, sizeof leaf->value);
+ if (lyp_parse_value_type(leaf, &((struct lys_node_leaf *)leaf->schema)->type, 0)) {
+ return EXIT_FAILURE;
+ }
}
- } else if (((struct lyd_node_leaf_list *)node)->value_type == LY_TYPE_INST) {
- if (unres_data_add(unres, (struct lyd_node *)node, UNRES_INSTID)) {
- return EXIT_FAILURE;
+ } else {
+ /* if leafref or instance-identifier, store the node for later resolving */
+ if (leaf->value_type == LY_TYPE_LEAFREF && !leaf->value.leafref) {
+ if (unres_data_add(unres, (struct lyd_node *)node, UNRES_LEAFREF)) {
+ return EXIT_FAILURE;
+ }
+ } else if (leaf->value_type == LY_TYPE_INST) {
+ if (unres_data_add(unres, (struct lyd_node *)node, UNRES_INSTID)) {
+ return EXIT_FAILURE;
+ }
}
}
}