Skip to content

Commit

Permalink
tree data UPDATE error on invalid new_path position
Browse files Browse the repository at this point in the history
Refs #2333
  • Loading branch information
michalvasko committed Jan 8, 2025
1 parent e035439 commit b32cda9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/tree_data_new.c
Original file line number Diff line number Diff line change
Expand Up @@ -1658,14 +1658,14 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
LY_ERR ret = LY_SUCCESS, r;
struct lyxp_expr *exp = NULL;
struct ly_path *p = NULL;
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent;
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent, *iter;
const struct lysc_node *schema;
const struct lyd_value *val = NULL;
ly_bool store_only = (options & LYD_NEW_VAL_STORE_ONLY) ? 1 : 0;
ly_bool any_use_value = (options & LYD_NEW_ANY_USE_VALUE) ? 1 : 0;
LY_ARRAY_COUNT_TYPE path_idx = 0, orig_count = 0;
LY_VALUE_FORMAT format;
uint32_t hints;
uint32_t hints, count;

assert(parent || ctx);
assert(path && ((path[0] == '/') || parent));
Expand Down Expand Up @@ -1712,7 +1712,7 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
goto cleanup;
} /* else we were not searching for the whole path */
} else if (r == LY_EINCOMPLETE) {
/* some nodes were found, adjust the iterator to the next segment */
/* some nodes were found, adjust the iterator to the next segment to be created */
++path_idx;
} else if (r == LY_ENOTFOUND) {
/* we will create the nodes from top-level, default behavior (absolute path), or from the parent (relative path) */
Expand All @@ -1731,6 +1731,29 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
LY_ARRAY_INCREMENT(p);
}

if ((path_idx < LY_ARRAY_COUNT(p)) && lysc_is_dup_inst_list(p[path_idx].node) && p[path_idx].predicates &&
(p[path_idx].predicates[0].type == LY_PATH_PREDTYPE_POSITION)) {
/* check the used position of a key-less list or state leaf-list */
count = 0;
LYD_LIST_FOR_INST(node ? lyd_child(node) : parent, p[path_idx].node, iter) {
++count;
}

if (count + 1 < p[path_idx].predicates[0].position) {
if (count) {
LOGVAL(ctx, LYVE_REFERENCE,
"Cannot create \"%s\" on position %" PRIu64 ", only %" PRIu32 " instance%s exist%s.",
p[path_idx].node->name, p[path_idx].predicates[0].position, count, (count > 1) ? "s" : "",
(count > 1) ? "" : "s");
} else {
LOGVAL(ctx, LYVE_REFERENCE, "Cannot create \"%s\" on position %" PRIu64 ", no instances exist.",
p[path_idx].node->name, p[path_idx].predicates[0].position);
}
ret = LY_EINVAL;
goto cleanup;
}
}

/* create all the non-existing nodes in a loop */
for ( ; path_idx < LY_ARRAY_COUNT(p); ++path_idx) {
cur_parent = node;
Expand Down
8 changes: 8 additions & 0 deletions tests/utests/data/test_new.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,14 @@ test_path(void **state)
assert_int_equal(ret, LY_SUCCESS);
assert_non_null(node);

/* too high index */
ret = lyd_new_path2(root, NULL, "/a:c2/l3[8]", NULL, 0, 0, 0, NULL, &node);
assert_int_equal(ret, LY_EINVAL);
CHECK_LOG_CTX("Cannot create \"l3\" on position 8, only 6 instances exist.", NULL, 0);
ret = lyd_new_path2(root, NULL, "/a:l2[2]", NULL, 0, 0, 0, NULL, &node);
assert_int_equal(ret, LY_EINVAL);
CHECK_LOG_CTX("Cannot create \"l2\" on position 2, no instances exist.", NULL, 0);

lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS);
assert_string_equal(str,
"<c2 xmlns=\"urn:tests:a\">\n"
Expand Down

0 comments on commit b32cda9

Please sign in to comment.