Skip to content

Commit 7e3672c

Browse files
committed
validate: unions with leafrefs may return misleading error codes
When a leafref is not found in a union, it should not return an error indicating the value for the leafref wouldn't match the restrictions for a target but instead just say the leafref target wasn't found. The only data that should indicate the error message for data type restrictions is data associated with the target itself, not leafrefs. Signed-off-by: Brad House <[email protected]>
1 parent 529a594 commit 7e3672c

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

src/plugins_types/union.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,31 @@ lyb_parse_union(const void *lyb_data, size_t lyb_data_len, uint32_t *type_idx, c
150150
}
151151
}
152152

153+
static void
154+
union_lref_error_rewrite(const struct lyd_node *ctx_node, struct ly_err_item *err, struct lysc_type *type, const void *value, size_t value_len)
155+
{
156+
struct lysc_type_leafref *lref;
157+
char *valstr = NULL;
158+
159+
if ((err == NULL) || (type->basetype != LY_TYPE_LEAFREF)) {
160+
return;
161+
}
162+
163+
lref = (struct lysc_type_leafref *)type;
164+
free(err->apptag);
165+
err->apptag = strdup("instance-required");
166+
167+
free(err->msg);
168+
169+
if (lyd_get_value(ctx_node) != NULL) {
170+
valstr = strdup(lyd_get_value(ctx_node));
171+
} else {
172+
valstr = strndup((const char *)value, value_len);
173+
}
174+
asprintf(&err->msg, LY_ERRMSG_NOLREF_VAL, valstr, lyxp_get_expr(lref->path));
175+
free(valstr);
176+
}
177+
153178
/**
154179
* @brief Store (and validate) subvalue as a specific type.
155180
*
@@ -190,6 +215,9 @@ union_store_type(const struct ly_ctx *ctx, struct lysc_type_union *type_u, uint3
190215
if ((rc != LY_SUCCESS) && (rc != LY_EINCOMPLETE)) {
191216
/* clear any leftover/freed garbage */
192217
memset(&subvalue->value, 0, sizeof subvalue->value);
218+
219+
/* if this is a leafref, lets make sure we propagate the appropriate error, and not a type validation failure */
220+
union_lref_error_rewrite(ctx_node, *err, type_u->types[ti], value, value_len);
193221
return rc;
194222
}
195223

@@ -228,6 +256,11 @@ union_store_type(const struct ly_ctx *ctx, struct lysc_type_union *type_u, uint3
228256
if ((rc != LY_SUCCESS) && (rc != LY_EINCOMPLETE)) {
229257
/* clear any leftover/freed garbage */
230258
memset(&subvalue->value, 0, sizeof subvalue->value);
259+
260+
/* if this is a leafref, lets make sure we propagate the appropriate error, and not a type validation failure */
261+
if (type->basetype == LY_TYPE_LEAFREF) {
262+
union_lref_error_rewrite(ctx_node, *err, type, value, value_len);
263+
}
231264
return rc;
232265
}
233266

tests/utests/types/union.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ test_data_xml(void **state)
105105
TEST_ERROR_XML2("",
106106
"defs", "", "un1", "123456789012345678901", LY_EVALID);
107107
CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found:\n"
108-
" libyang 2 - leafref, version 1: Invalid type int8 value \"123456789012345678901\".\n"
109-
" libyang 2 - leafref, version 1: Invalid type int64 value \"123456789012345678901\".\n"
108+
" libyang 2 - leafref, version 1: Invalid leafref value \"123456789012345678901\" - no target instance \"/int8\" with the same value.\n"
109+
" libyang 2 - leafref, version 1: Invalid leafref value \"123456789012345678901\" - no target instance \"/int64\" with the same value.\n"
110110
" libyang 2 - identityref, version 1: Invalid identityref \"123456789012345678901\" value - identity not found in module \"defs\".\n"
111111
" libyang 2 - instance-identifier, version 1: Invalid instance-identifier \"123456789012345678901\" value - syntax error.\n"
112112
" libyang 2 - string, version 1: Unsatisfied length - string \"123456789012345678901\" length is not allowed.\n",
@@ -295,7 +295,8 @@ test_validation(void **state)
295295
assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT, NULL));
296296
CHECK_LOG_CTX("Invalid LYB union value - no matching subtype found:\n"
297297
" libyang 2 - leafref, version 1: Invalid leafref value \"one\" - no target instance \"../../a/name\" with the same value.\n"
298-
" libyang 2 - leafref, version 1: Invalid type uint32 value \"one\".\n", "/lref:test/community[name='test']/view", 0);
298+
" libyang 2 - leafref, version 1: Invalid leafref value \"one\" - no target instance \"../../b/name\" with the same value.\n",
299+
"/lref:test/community[name='test']/view", 0);
299300

300301
lyd_free_all(tree);
301302
}

0 commit comments

Comments
 (0)