Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/xpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -3704,7 +3704,8 @@ xpath_bit_is_set(struct lyxp_set **args, uint32_t UNUSED(arg_count), struct lyxp
LY_CHECK_RET(rc);

set_fill_boolean(set, 0);
if (args[0]->used && (args[0]->val.nodes[0].node->schema->nodetype & LYD_NODE_TERM)) {
if (args[0]->used && (args[0]->val.nodes[0].type == LYXP_NODE_ELEM) && args[0]->val.nodes[0].node->schema &&
(args[0]->val.nodes[0].node->schema->nodetype & LYD_NODE_TERM)) {
leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
val = &leaf->value;
if (val->realtype->basetype == LY_TYPE_UNION) {
Expand Down Expand Up @@ -4123,10 +4124,10 @@ xpath_deref(struct lyxp_set **args, uint32_t UNUSED(arg_count), struct lyxp_set

/* clear */
lyxp_set_free_content(set);
if (args[0]->used) {
if (args[0]->used && (args[0]->val.nodes[0].type == LYXP_NODE_ELEM)) {
leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
sleaf = (struct lysc_node_leaf *)leaf->schema;
if (sleaf->nodetype & LYD_NODE_TERM) {
if (sleaf && (sleaf->nodetype & LYD_NODE_TERM)) {
ret = xpath_deref_type(&leaf->node, &leaf->value, sleaf->type, set);
}
}
Expand Down Expand Up @@ -4343,10 +4344,10 @@ xpath_enum_value(struct lyxp_set **args, uint32_t UNUSED(arg_count), struct lyxp
}

set_fill_number(set, NAN);
if (args[0]->used) {
if (args[0]->used && (args[0]->val.nodes[0].type == LYXP_NODE_ELEM)) {
leaf = (struct lyd_node_term *)args[0]->val.nodes[0].node;
sleaf = (struct lysc_node_leaf *)leaf->schema;
if ((sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_ENUM)) {
if (sleaf && (sleaf->nodetype & (LYS_LEAF | LYS_LEAFLIST)) && (sleaf->type->basetype == LY_TYPE_ENUM)) {
set_fill_number(set, leaf->value.enum_item->value);
}
}
Expand Down
94 changes: 94 additions & 0 deletions tests/utests/basic/test_xpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,99 @@ test_number(void **state)
lyd_free_siblings(tree);
}

static void
test_no_value(void **state)
{
const char *schema_c =
"module c {\n"
" namespace urn:tests:c;\n"
" prefix c;\n"
" yang-version 1.1;\n"
"\n"
" identity base;\n"
" identity one {\n"
" base base;\n"
" }\n"
"\n"
" leaf t {\n"
" type string;\n"
" }\n"
" container ce {\n"
" presence \"test\";\n"
" leaf v {\n"
" when \"string(enum-value(.)) = 'NaN'\";\n"
" type enumeration {\n"
" enum x;\n"
" }\n"
" mandatory true;\n"
" }\n"
" }\n"
" container cb {\n"
" presence \"test\";\n"
" leaf v {\n"
" when \"not(bit-is-set(., 'f'))\";\n"
" type bits {\n"
" bit f;\n"
" }\n"
" mandatory true;\n"
" }\n"
" }\n"
" container cd {\n"
" presence \"test\";\n"
" leaf v {\n"
" when \"not(deref(.))\";\n"
" type leafref {\n"
" path \"/c:t\";\n"
" }\n"
" mandatory true;\n"
" }\n"
" }\n"
" container ci {\n"
" presence \"test\";\n"
" leaf v {\n"
" when \"not(derived-from-or-self(., 'c:one'))\";\n"
" type identityref {\n"
" base base;\n"
" }\n"
" mandatory true;\n"
" }\n"
" }\n"
"}";
struct lyd_node *tree;
ly_bool r;

UTEST_ADD_MODULE(schema_c, LYS_IN_YANG, NULL, NULL);

/* the when of a missing node is evaluated on an opaque dummy node without a value */
CHECK_PARSE_LYD_PARAM("<ce xmlns=\"urn:tests:c\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
CHECK_LOG_CTX("Mandatory node \"v\" instance does not exist.", "/c:ce", 0);

CHECK_PARSE_LYD_PARAM("<cb xmlns=\"urn:tests:c\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
CHECK_LOG_CTX("Mandatory node \"v\" instance does not exist.", "/c:cb", 0);

CHECK_PARSE_LYD_PARAM("<cd xmlns=\"urn:tests:c\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
CHECK_LOG_CTX("Mandatory node \"v\" instance does not exist.", "/c:cd", 0);

CHECK_PARSE_LYD_PARAM("<ci xmlns=\"urn:tests:c\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
CHECK_LOG_CTX("Mandatory node \"v\" instance does not exist.", "/c:ci", 0);

/* the root node has no value either */
assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, "<t xmlns=\"urn:tests:c\">val</t>", LYD_XML,
LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
assert_non_null(tree);

assert_int_equal(LY_SUCCESS, lyd_eval_xpath(tree, "string(enum-value(/)) = 'NaN'", &r));
assert_int_equal(r, 1);

assert_int_equal(LY_SUCCESS, lyd_eval_xpath(tree, "bit-is-set(/, 'f')", &r));
assert_int_equal(r, 0);

assert_int_equal(LY_SUCCESS, lyd_eval_xpath(tree, "deref(/)", &r));
assert_int_equal(r, 0);

lyd_free_all(tree);
}

int
main(void)
{
Expand All @@ -1346,6 +1439,7 @@ main(void)
UTEST(test_mod, setup),
UTEST(test_anydata, setup),
UTEST(test_number, setup),
UTEST(test_no_value, setup),
};

return cmocka_run_group_tests(tests, NULL, NULL);
Expand Down
Loading