Skip to content

Commit c730448

Browse files
committed
xpath BUGFIX handle input/output name conflicts
Fixes #2137
1 parent d108cc5 commit c730448

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

src/xpath.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7943,7 +7943,7 @@ eval_name_test_with_predicate_get_scnode(const struct ly_ctx *ctx, const struct
79437943
uint32_t name_len, const struct lys_module *moveto_mod, enum lyxp_node_type root_type, LY_VALUE_FORMAT format,
79447944
const struct lysc_node **found)
79457945
{
7946-
const struct lysc_node *scnode;
7946+
const struct lysc_node *scnode, *scnode2;
79477947
const struct lys_module *mod;
79487948
uint32_t idx = 0;
79497949

@@ -7981,7 +7981,19 @@ eval_name_test_with_predicate_get_scnode(const struct ly_ctx *ctx, const struct
79817981
}
79827982

79837983
/* search in children, do not repeat the same search */
7984-
scnode = lys_find_child(node->schema, moveto_mod, name, name_len, 0, 0);
7984+
if (node->schema->nodetype & (LYS_RPC | LYS_ACTION)) {
7985+
/* make sure the node is unique, whether in input or output */
7986+
scnode = lys_find_child(node->schema, moveto_mod, name, name_len, 0, 0);
7987+
scnode2 = lys_find_child(node->schema, moveto_mod, name, name_len, 0, LYS_GETNEXT_OUTPUT);
7988+
if (scnode && scnode2) {
7989+
/* conflict, do not use hashes */
7990+
scnode = NULL;
7991+
} else if (scnode2) {
7992+
scnode = scnode2;
7993+
}
7994+
} else {
7995+
scnode = lys_find_child(node->schema, moveto_mod, name, name_len, 0, 0);
7996+
}
79857997
} /* else skip redundant search */
79867998

79877999
/* additional context check */

tests/utests/basic/test_xpath.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ const char *schema_a =
8888
" type string;\n"
8989
" }\n"
9090
" }\n"
91+
"\n"
92+
" rpc r {\n"
93+
" input {\n"
94+
" leaf l {\n"
95+
" type string;\n"
96+
" }\n"
97+
" }\n"
98+
" output {\n"
99+
" leaf l {\n"
100+
" type string;\n"
101+
" }\n"
102+
" }\n"
103+
" }\n"
91104
"}";
92105

93106
static int
@@ -382,6 +395,31 @@ test_hash(void **state)
382395
lyd_free_all(tree);
383396
}
384397

398+
static void
399+
test_rpc(void **state)
400+
{
401+
const char *data =
402+
"<r xmlns=\"urn:tests:a\">\n"
403+
" <l>val</l>\n"
404+
"</r>";
405+
struct ly_in *in;
406+
struct lyd_node *tree;
407+
struct ly_set *set;
408+
409+
assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
410+
assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_REPLY_YANG, &tree, NULL));
411+
ly_in_free(in, 0);
412+
assert_non_null(tree);
413+
414+
/* name collision input/output, hashes are not used */
415+
assert_int_equal(LY_SUCCESS, lyd_find_xpath(tree, "/a:r/l", &set));
416+
assert_int_equal(1, set->count);
417+
418+
ly_set_free(set, NULL);
419+
420+
lyd_free_all(tree);
421+
}
422+
385423
static void
386424
test_toplevel(void **state)
387425
{
@@ -481,7 +519,7 @@ test_atomize(void **state)
481519

482520
/* some random paths just making sure the API function works */
483521
assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set));
484-
assert_int_equal(6, set->count);
522+
assert_int_equal(7, set->count);
485523
ly_set_free(set, NULL);
486524

487525
/* all nodes from all modules (including internal, which can change easily, so check just the test modules) */
@@ -498,7 +536,7 @@ test_atomize(void **state)
498536
ly_set_free(set, NULL);
499537

500538
assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/*", 0, &set));
501-
assert_int_equal(13, set->count);
539+
assert_int_equal(14, set->count);
502540
ly_set_free(set, NULL);
503541

504542
/*
@@ -532,7 +570,7 @@ test_atomize(void **state)
532570

533571
/* descendant-or-self */
534572
assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*/descendant-or-self::c", 0, &set));
535-
assert_int_equal(7, set->count);
573+
assert_int_equal(8, set->count);
536574
ly_set_free(set, NULL);
537575

538576
/* following */
@@ -547,11 +585,11 @@ test_atomize(void **state)
547585

548586
/* parent */
549587
assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:*/c/parent::l1", 0, &set));
550-
assert_int_equal(7, set->count);
588+
assert_int_equal(8, set->count);
551589
ly_set_free(set, NULL);
552590

553591
assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/child::a:c//..", 0, &set));
554-
assert_int_equal(8, set->count);
592+
assert_int_equal(11, set->count);
555593
ly_set_free(set, NULL);
556594

557595
/* preceding */
@@ -1062,6 +1100,7 @@ main(void)
10621100
UTEST(test_union, setup),
10631101
UTEST(test_invalid, setup),
10641102
UTEST(test_hash, setup),
1103+
UTEST(test_rpc, setup),
10651104
UTEST(test_toplevel, setup),
10661105
UTEST(test_atomize, setup),
10671106
UTEST(test_canonize, setup),

0 commit comments

Comments
 (0)