diff --git a/src/path.c b/src/path.c index 516fe5720..73883d754 100644 --- a/src/path.c +++ b/src/path.c @@ -1068,7 +1068,17 @@ ly_path_compile_deref(const struct ly_ctx *ctx, const struct lysc_node *ctx_node LY_CHECK_GOTO(ret = ly_path_compile_leafref(ctx, ctx_node, top_ext, &expr2, oper, target, format, prefix_data, &path2), cleanup); node2 = path2[LY_ARRAY_COUNT(path2) - 1].node; + if ((node2->nodetype != LYS_LEAF) && (node2->nodetype != LYS_LEAFLIST)) { + LOGVAL(ctx, LYVE_XPATH, "The deref function target node \"%s\" is not leaf nor leaflist", node2->name); + ret = LY_EVALID; + goto cleanup; + } deref_leaf_node = (const struct lysc_node_leaf *)node2; + if (deref_leaf_node->type->basetype != LY_TYPE_LEAFREF) { + LOGVAL(ctx, LYVE_XPATH, "The deref function target node \"%s\" is not leafref", node2->name); + ret = LY_EVALID; + goto cleanup; + } lref = (const struct lysc_type_leafref *)deref_leaf_node->type; LY_CHECK_GOTO(ret = ly_path_append(ctx, path2, path), cleanup); ly_path_free(ctx, path2); @@ -1172,7 +1182,6 @@ _ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, con (expr->tokens[tok_idx] == LYXP_TOKEN_FUNCNAME)) { /* deref function */ ret = ly_path_compile_deref(ctx, ctx_node, top_ext, expr, oper, target, format, prefix_data, &tok_idx, path); - ctx_node = (*path)[LY_ARRAY_COUNT(*path) - 1].node; goto cleanup; } else if (expr->tokens[tok_idx] == LYXP_TOKEN_OPER_PATH) { /* absolute path */ diff --git a/tests/utests/types/leafref.c b/tests/utests/types/leafref.c index 7005d08bf..21e91cd70 100644 --- a/tests/utests/types/leafref.c +++ b/tests/utests/types/leafref.c @@ -241,6 +241,38 @@ test_data_xpath_json(void **state) lyd_free_all(tree); } +static void +test_xpath_invalid_schema(void **state) +{ + const char *schema1, *schema2; + + ly_ctx_set_options(UTEST_LYCTX, LY_CTX_LEAFREF_EXTENDED); + schema1 = MODULE_CREATE_YANG("xp_test", + "list l1 {key t1;" + "leaf t1 {type uint8;}" + "list l2 {key t2;" + "leaf t2 {type uint8;}" + "leaf-list l3 {type uint8;}" + "}}" + "leaf r1 {type leafref {path \"deref(../l1)/../l2/t2\";}}"); + + UTEST_INVALID_MODULE(schema1, LYS_IN_YANG, NULL, LY_EVALID) + CHECK_LOG_CTX("The deref function target node \"l1\" is not leaf nor leaflist", "Schema location \"/xp_test:r1\"."); + + schema2 = MODULE_CREATE_YANG("xp_test", + "list l1 {key t1;" + "leaf t1 {type uint8;}" + "list l2 {key t2;" + "leaf t2 {type uint8;}" + "leaf-list l3 {type uint8;}" + "}}" + "leaf r1 {type uint8;}" + "leaf r2 {type leafref {path \"deref(../r1)/../l2/t2\";}}"); + + UTEST_INVALID_MODULE(schema2, LYS_IN_YANG, NULL, LY_EVALID) + CHECK_LOG_CTX("The deref function target node \"r1\" is not leafref", "Schema location \"/xp_test:r2\"."); +} + int main(void) { @@ -249,6 +281,7 @@ main(void) UTEST(test_data_json), UTEST(test_plugin_lyb), UTEST(test_data_xpath_json), + UTEST(test_xpath_invalid_schema) }; return cmocka_run_group_tests(tests, NULL, NULL);