Skip to content

Commit b5f56b3

Browse files
committed
schema compile BUGFIX leafref circular chain with a union
1 parent 599d975 commit b5f56b3

2 files changed

Lines changed: 66 additions & 12 deletions

File tree

src/schema_compile.c

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,49 @@ lys_compile_unres_disabled_bitenum(struct lysc_ctx *ctx, struct lysc_node_leaf *
810810
return LY_SUCCESS;
811811
}
812812

813+
/**
814+
* @brief Check a leafref for circular references.
815+
*
816+
* @param[in] type Referenced type, is checked recursively for other leafrefs.
817+
* @param[in] lref Initial leafref type that cannot be referenced.
818+
* @return LY_SUCCESS on success;
819+
* @return LY_EVALID on a circular chein of leafrefs.
820+
*/
821+
static LY_ERR
822+
lys_compile_leafref_circ_check(const struct lysc_type *type, const struct lysc_type *lref)
823+
{
824+
const struct lysc_type_union *un;
825+
LY_ARRAY_COUNT_TYPE u;
826+
827+
if (!type) {
828+
/* not resolved yet */
829+
return LY_SUCCESS;
830+
}
831+
832+
if (type == lref) {
833+
/* circular chain detected */
834+
return LY_EVALID;
835+
}
836+
837+
switch (type->basetype) {
838+
case LY_TYPE_LEAFREF:
839+
/* check the referenced type */
840+
LY_CHECK_RET(lys_compile_leafref_circ_check(((struct lysc_type_leafref *)type)->realtype, lref));
841+
break;
842+
case LY_TYPE_UNION:
843+
/* check all the union types */
844+
un = (struct lysc_type_union *)type;
845+
LY_ARRAY_FOR(un->types, u) {
846+
LY_CHECK_RET(lys_compile_leafref_circ_check(un->types[u], lref));
847+
}
848+
default:
849+
/* no more leafref references */
850+
break;
851+
}
852+
853+
return LY_SUCCESS;
854+
}
855+
813856
/**
814857
* @brief Check leafref for its target existence on a complete compiled schema tree.
815858
*
@@ -825,7 +868,6 @@ lys_compile_unres_leafref(struct lysc_ctx *ctx, const struct lysc_node *node, st
825868
{
826869
const struct lysc_node *target = NULL;
827870
struct ly_path *p;
828-
struct lysc_type *type;
829871
uint16_t flg;
830872

831873
assert(node->nodetype & (LYS_LEAF | LYS_LEAFLIST));
@@ -881,17 +923,12 @@ lys_compile_unres_leafref(struct lysc_ctx *ctx, const struct lysc_node *node, st
881923
}
882924

883925
/* check for circular chain of leafrefs */
884-
for (type = ((struct lysc_node_leaf *)target)->type;
885-
type && (type->basetype == LY_TYPE_LEAFREF);
886-
type = ((struct lysc_type_leafref *)type)->realtype) {
887-
if (type == (struct lysc_type *)lref) {
888-
/* circular chain detected */
889-
LOG_LOCSET(node);
890-
LOGVAL(ctx->ctx, NULL, LYVE_REFERENCE, "Invalid leafref path \"%s\" - circular chain of leafrefs detected.",
891-
lref->path->expr);
892-
LOG_LOCBACK(1);
893-
return LY_EVALID;
894-
}
926+
if (lys_compile_leafref_circ_check(((struct lysc_node_leaf *)target)->type, (struct lysc_type *)lref)) {
927+
LOG_LOCSET(node);
928+
LOGVAL(ctx->ctx, NULL, LYVE_REFERENCE, "Invalid leafref path \"%s\" - circular chain of leafrefs detected.",
929+
lref->path->expr);
930+
LOG_LOCBACK(1);
931+
return LY_EVALID;
895932
}
896933

897934
/* store the type */

tests/utests/schema/test_tree_schema_compile.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,23 @@ test_type_leafref(void **state)
20812081
"leaf ref3 {type leafref {path /ref4;}}\n"
20822082
"leaf ref4 {type leafref {path /ref1;}}}", LYS_IN_YANG, &mod));
20832083
CHECK_LOG_CTX("Invalid leafref path \"/ref1\" - circular chain of leafrefs detected.", "/aaa:ref4", 0);
2084+
2085+
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module leafref-unions {\n"
2086+
" namespace \"http://example.com/leafref-unions\"; prefix \"lu\";\n"
2087+
" \n"
2088+
" container config {\n"
2089+
" leaf circular-ref-1 {\n"
2090+
" type union {\n"
2091+
" type leafref {\n"
2092+
" path \"../circular-ref-1\";\n"
2093+
" }\n"
2094+
" }\n"
2095+
" default \"circular-value\";\n"
2096+
" }\n"
2097+
" }\n"
2098+
"}", LYS_IN_YANG, NULL));
2099+
CHECK_LOG_CTX("Invalid leafref path \"../circular-ref-1\" - circular chain of leafrefs detected.",
2100+
"/leafref-unions:config/circular-ref-1", 0);
20842101
}
20852102

20862103
static void

0 commit comments

Comments
 (0)