union BUGFIX validating LYB values
The value needs tobe interpreted based on
the stored type in the value.
Reverts 9372871ed84c46d0f7e1811a3062f0e878bd3c0d
Fixes #1981
diff --git a/src/plugins_types/union.c b/src/plugins_types/union.c
index 509be6c..a358e43 100644
--- a/src/plugins_types/union.c
+++ b/src/plugins_types/union.c
@@ -365,6 +365,7 @@
LY_ERR ret = LY_SUCCESS;
struct lysc_type_union *type_u = (struct lysc_type_union *)type;
struct lyd_value_union *subvalue = storage->subvalue;
+ uint32_t type_idx;
*err = NULL;
@@ -373,9 +374,16 @@
* we have to perform union value storing again from scratch */
subvalue->value.realtype->plugin->free(ctx, &subvalue->value);
- /* use the first usable subtype to store the value */
- ret = union_find_type(ctx, type_u->types, subvalue, 1, ctx_node, tree, NULL, NULL, err);
- LY_CHECK_RET(ret);
+ if (subvalue->format == LY_VALUE_LYB) {
+ /* use the specific type to store the value */
+ lyb_parse_union(subvalue->original, 0, &type_idx, NULL, NULL);
+ ret = union_store_type(ctx, type_u->types[type_idx], subvalue, 1, ctx_node, tree, NULL, err);
+ LY_CHECK_RET(ret);
+ } else {
+ /* use the first usable subtype to store the value */
+ ret = union_find_type(ctx, type_u->types, subvalue, 1, ctx_node, tree, NULL, NULL, err);
+ LY_CHECK_RET(ret);
+ }
/* success, update the canonical value, if any generated */
lydict_remove(ctx, storage->_canonical);
diff --git a/tests/utests/types/union.c b/tests/utests/types/union.c
index 9a0705a..3522795 100644
--- a/tests/utests/types/union.c
+++ b/tests/utests/types/union.c
@@ -124,12 +124,59 @@
TEST_SUCCESS_LYB("lyb", "un1", "");
}
+static void
+test_validation(void **state)
+{
+ const char *schema, *data;
+ struct lyd_node *tree;
+ char *out;
+
+ schema = MODULE_CREATE_YANG("val",
+ "leaf l1 {\n"
+ " type union {\n"
+ " type uint32 {\n"
+ " range \"0..1048575\";\n"
+ " }\n"
+ " type enumeration {\n"
+ " enum auto;\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "leaf int8 {type int8 {range 10..20;}}\n"
+ "leaf l2 {\n"
+ " type union {\n"
+ " type leafref {path /int8; require-instance true;}\n"
+ " type string;\n"
+ " }\n"
+ "}\n");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* parse from LYB */
+ data = "<l1 xmlns=\"urn:tests:val\">auto</l1><int8 xmlns=\"urn:tests:val\">15</int8><l2 xmlns=\"urn:tests:val\">15</l2>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ assert_int_equal(LY_SUCCESS, lyd_print_mem(&out, tree, LYD_LYB, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS));
+ lyd_free_all(tree);
+ CHECK_PARSE_LYD_PARAM(out, LYD_LYB, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ free(out);
+
+ /* validate */
+ assert_int_equal(LY_SUCCESS, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT, NULL));
+
+ /* print and compare */
+ assert_int_equal(LY_SUCCESS, lyd_print_mem(&out, tree, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS));
+ assert_string_equal(out, data);
+
+ free(out);
+ lyd_free_all(tree);
+}
+
int
main(void)
{
const struct CMUnitTest tests[] = {
UTEST(test_data_xml),
UTEST(test_plugin_lyb),
+ UTEST(test_validation),
};
return cmocka_run_group_tests(tests, NULL, NULL);