resolve BUGFIX leafref has a data path, not schema
diff --git a/src/resolve.c b/src/resolve.c
index 820e4cc..ac40f9d 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -3756,6 +3756,7 @@
resolve_path_predicate_schema(const char *path, const struct lys_node *context_node,
struct lys_node *parent, const struct lys_node *op_node)
{
+ const struct lys_module *trg_mod;
const struct lys_node *src_node, *dst_node;
const char *path_key_expr, *source, *sour_pref, *dest, *dest_pref;
int pke_len, sour_len, sour_pref_len, dest_len, dest_pref_len, pke_parsed, parsed = 0;
@@ -3771,11 +3772,12 @@
path += i;
/* source (must be leaf) */
- if (!sour_pref) {
- sour_pref = context_node->module->name;
+ if (sour_pref) {
+ trg_mod = lys_get_import_module(lys_node_module(parent), NULL, 0, sour_pref, sour_pref_len);
+ } else {
+ trg_mod = NULL;
}
- rc = lys_get_sibling(context_node->child, sour_pref, sour_pref_len, source, sour_len,
- LYS_LEAF | LYS_LEAFLIST | LYS_AUGMENT, &src_node);
+ rc = lys_get_data_sibling(trg_mod, context_node->child, source, sour_len, LYS_LEAF | LYS_LEAFLIST, &src_node);
if (rc) {
LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path-parsed);
return 0;
@@ -3805,11 +3807,12 @@
}
first_iter = 1;
while (1) {
- if (!dest_pref) {
- dest_pref = dst_node->module->name;
+ if (dest_pref) {
+ trg_mod = lys_get_import_module(lys_node_module(parent), NULL, 0, dest_pref, dest_pref_len);
+ } else {
+ trg_mod = NULL;
}
- rc = lys_get_sibling(dst_node->child, dest_pref, dest_pref_len, dest, dest_len,
- LYS_CONTAINER | LYS_LIST | LYS_LEAF | LYS_AUGMENT, &dst_node);
+ rc = lys_get_data_sibling(trg_mod, dst_node->child, dest, dest_len, LYS_CONTAINER | LYS_LIST | LYS_LEAF, &dst_node);
if (rc) {
LOGVAL(LYE_NORESOLV, parent ? LY_VLOG_LYS : LY_VLOG_NONE, parent, "leafref predicate", path_key_expr);
return 0;
@@ -3985,11 +3988,8 @@
}
}
- if (!prefix) {
- prefix = mod_start->name;
- }
-
- rc = lys_get_sibling(node, prefix, pref_len, name, nam_len, LYS_ANY & ~(LYS_USES | LYS_GROUPING), &node);
+ rc = lys_get_data_sibling(mod, node, name, nam_len, LYS_LIST | LYS_CONTAINER | LYS_RPC | LYS_ACTION | LYS_NOTIF
+ | LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA, &node);
if (rc) {
LOGVAL(LYE_NORESOLV, parent_tpdf ? LY_VLOG_NONE : LY_VLOG_LYS, parent_tpdf ? NULL : parent, "leafref", path);
return EXIT_FAILURE;
@@ -5296,7 +5296,8 @@
len = strlen(keys_str);
}
- rc = lys_get_sibling(list->child, lys_main_module(list->module)->name, 0, keys_str, len, LYS_LEAF, (const struct lys_node **)&list->keys[i]);
+ rc = lys_get_data_sibling(lys_node_module((struct lys_node *)list), list->child, keys_str, len, LYS_LEAF,
+ (const struct lys_node **)&list->keys[i]);
if (rc) {
LOGVAL(LYE_INRESOLV, LY_VLOG_LYS, list, "list keys", keys_str);
return EXIT_FAILURE;
diff --git a/src/tree_data.c b/src/tree_data.c
index d533821..2908a6d 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -639,7 +639,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_RPC | LYS_ACTION, &snode)
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_RPC | LYS_ACTION, &snode)
|| !snode) {
ly_errno = LY_EINVAL;
return NULL;
@@ -725,7 +725,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_LEAFLIST | LYS_LEAF, &snode) || !snode) {
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_LEAFLIST | LYS_LEAF, &snode) || !snode) {
ly_errno = LY_EINVAL;
return NULL;
}
@@ -966,7 +966,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_ANYDATA, &snode) || !snode) {
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_ANYDATA, &snode) || !snode) {
return NULL;
}
@@ -989,7 +989,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_RPC | LYS_ACTION, &snode)
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_RPC | LYS_ACTION, &snode)
|| !snode) {
return NULL;
}
@@ -1013,7 +1013,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_LEAFLIST | LYS_LEAF, &snode) || !snode) {
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_LEAFLIST | LYS_LEAF, &snode) || !snode) {
ly_errno = LY_EINVAL;
return NULL;
}
@@ -1038,7 +1038,7 @@
return NULL;
}
- if (lys_get_data_sibling(module, siblings, name, LYS_ANYDATA, &snode) || !snode) {
+ if (lys_get_data_sibling(module, siblings, name, strlen(name), LYS_ANYDATA, &snode) || !snode) {
return NULL;
}
@@ -4342,14 +4342,21 @@
lyd_dup_common(struct lyd_node *parent, struct lyd_node *new, const struct lyd_node *orig, struct ly_ctx *ctx)
{
struct lyd_attr *attr;
+ const struct lys_module *trg_mod;
/* fill common part */
if (ctx) {
/* we are changing the context, so we have to get the correct schema node in the new context */
if (parent) {
+ trg_mod = lys_get_import_module(lys_node_module(parent->schema), NULL, 0, orig->schema->module->name,
+ strlen(orig->schema->module->name));
+ if (!trg_mod) {
+ LOGINT;
+ return EXIT_FAILURE;
+ }
/* we know its parent, so we can start with it */
- lys_get_sibling(parent->schema->child, orig->schema->module->name, 0, orig->schema->name, 0,
- orig->schema->nodetype, (const struct lys_node **)&new->schema);
+ lys_get_data_sibling(trg_mod, parent->schema->child, orig->schema->name, strlen(orig->schema->name),
+ orig->schema->nodetype, (const struct lys_node **)&new->schema);
} else {
/* we have to search in complete context */
new->schema = lyd_get_schema_inctx(orig, ctx);
diff --git a/src/tree_internal.h b/src/tree_internal.h
index eda8b7c..c87f0fa 100644
--- a/src/tree_internal.h
+++ b/src/tree_internal.h
@@ -368,13 +368,14 @@
* @param[in] siblings Siblings to consider. They are first adjusted to
* point to the first sibling.
* @param[in] name Node name.
+ * @param[in] nam_len Node \p name length.
* @param[in] type ORed desired type of the node. 0 means any (data node) type.
* @param[out] ret Pointer to the node of the desired type. Can be NULL.
*
* @return EXIT_SUCCESS on success, EXIT_FAILURE on fail.
*/
-int lys_get_data_sibling(const struct lys_module *mod, const struct lys_node *siblings, const char *name, LYS_NODE type,
- const struct lys_node **ret);
+int lys_get_data_sibling(const struct lys_module *mod, const struct lys_node *siblings, const char *name, int nam_len,
+ LYS_NODE type, const struct lys_node **ret);
/**
* @brief Compare 2 list or leaf-list data nodes if they are the same from the YANG point of view. Logs directly.
diff --git a/src/tree_schema.c b/src/tree_schema.c
index a9541f2..109646a 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -138,7 +138,7 @@
/* try to find the node */
node = NULL;
- while ((node = lys_getnext(node, parent, mod, LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE))) {
+ while ((node = lys_getnext(node, parent, mod, LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE | LYS_GETNEXT_WITHINOUT))) {
if (!type || (node->nodetype & type)) {
/* module name comparison */
node_mod_name = lys_node_module(node)->name;
@@ -160,8 +160,8 @@
}
int
-lys_get_data_sibling(const struct lys_module *mod, const struct lys_node *siblings, const char *name, LYS_NODE type,
- const struct lys_node **ret)
+lys_get_data_sibling(const struct lys_module *mod, const struct lys_node *siblings, const char *name, int nam_len,
+ LYS_NODE type, const struct lys_node **ret)
{
const struct lys_node *node;
@@ -187,7 +187,7 @@
}
/* direct name check */
- if (ly_strequal(node->name, name, 0)) {
+ if (!strncmp(node->name, name, nam_len) && !node->name[nam_len]) {
if (ret) {
*ret = node;
}