Skip to content

Commit b32cda9

Browse files
committed
tree data UPDATE error on invalid new_path position
Refs #2333
1 parent e035439 commit b32cda9

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/tree_data_new.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,14 +1658,14 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
16581658
LY_ERR ret = LY_SUCCESS, r;
16591659
struct lyxp_expr *exp = NULL;
16601660
struct ly_path *p = NULL;
1661-
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent;
1661+
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent, *iter;
16621662
const struct lysc_node *schema;
16631663
const struct lyd_value *val = NULL;
16641664
ly_bool store_only = (options & LYD_NEW_VAL_STORE_ONLY) ? 1 : 0;
16651665
ly_bool any_use_value = (options & LYD_NEW_ANY_USE_VALUE) ? 1 : 0;
16661666
LY_ARRAY_COUNT_TYPE path_idx = 0, orig_count = 0;
16671667
LY_VALUE_FORMAT format;
1668-
uint32_t hints;
1668+
uint32_t hints, count;
16691669

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

1734+
if ((path_idx < LY_ARRAY_COUNT(p)) && lysc_is_dup_inst_list(p[path_idx].node) && p[path_idx].predicates &&
1735+
(p[path_idx].predicates[0].type == LY_PATH_PREDTYPE_POSITION)) {
1736+
/* check the used position of a key-less list or state leaf-list */
1737+
count = 0;
1738+
LYD_LIST_FOR_INST(node ? lyd_child(node) : parent, p[path_idx].node, iter) {
1739+
++count;
1740+
}
1741+
1742+
if (count + 1 < p[path_idx].predicates[0].position) {
1743+
if (count) {
1744+
LOGVAL(ctx, LYVE_REFERENCE,
1745+
"Cannot create \"%s\" on position %" PRIu64 ", only %" PRIu32 " instance%s exist%s.",
1746+
p[path_idx].node->name, p[path_idx].predicates[0].position, count, (count > 1) ? "s" : "",
1747+
(count > 1) ? "" : "s");
1748+
} else {
1749+
LOGVAL(ctx, LYVE_REFERENCE, "Cannot create \"%s\" on position %" PRIu64 ", no instances exist.",
1750+
p[path_idx].node->name, p[path_idx].predicates[0].position);
1751+
}
1752+
ret = LY_EINVAL;
1753+
goto cleanup;
1754+
}
1755+
}
1756+
17341757
/* create all the non-existing nodes in a loop */
17351758
for ( ; path_idx < LY_ARRAY_COUNT(p); ++path_idx) {
17361759
cur_parent = node;

tests/utests/data/test_new.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ test_path(void **state)
353353
assert_int_equal(ret, LY_SUCCESS);
354354
assert_non_null(node);
355355

356+
/* too high index */
357+
ret = lyd_new_path2(root, NULL, "/a:c2/l3[8]", NULL, 0, 0, 0, NULL, &node);
358+
assert_int_equal(ret, LY_EINVAL);
359+
CHECK_LOG_CTX("Cannot create \"l3\" on position 8, only 6 instances exist.", NULL, 0);
360+
ret = lyd_new_path2(root, NULL, "/a:l2[2]", NULL, 0, 0, 0, NULL, &node);
361+
assert_int_equal(ret, LY_EINVAL);
362+
CHECK_LOG_CTX("Cannot create \"l2\" on position 2, no instances exist.", NULL, 0);
363+
356364
lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS);
357365
assert_string_equal(str,
358366
"<c2 xmlns=\"urn:tests:a\">\n"

0 commit comments

Comments
 (0)