Skip to content

Commit 745a977

Browse files
committed
plugin types BUGFIX correct handling of union type
This bugfix corrects the behavior or union type plugin when used with LYPLG_TYPE_STORE_ONLY flag
1 parent deae604 commit 745a977

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

src/plugins_types/union.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,6 @@ lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, c
486486
ret = lyb_fill_subvalue(ctx, type_u, value, value_size_bits, prefix_data, subvalue, &options, unres, err);
487487
LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
488488
} else {
489-
/* to correctly resolve the union type, we need to always validate the value */
490-
options &= ~LYPLG_TYPE_STORE_ONLY;
491-
492489
/* store value to subvalue */
493490
ret = union_subvalue_assignment(value, value_size_bits, &subvalue->original, &subvalue->orig_size_bits, &options);
494491
LY_CHECK_GOTO(ret, cleanup);
@@ -501,6 +498,16 @@ lyplg_type_store_union(const struct ly_ctx *ctx, const struct lysc_type *type, c
501498
/* use the first usable subtype to store the value */
502499
ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, NULL, unres, err);
503500
LY_CHECK_GOTO((ret != LY_SUCCESS) && (ret != LY_EINCOMPLETE), cleanup);
501+
/* use the first usable and valid subtype to store the value */
502+
ret = union_find_type(ctx, type_u, subvalue, options & ~LYPLG_TYPE_STORE_ONLY, 0, NULL, NULL, NULL, NULL, unres,
503+
err);
504+
if (ret && (ret != LY_EINCOMPLETE) && (options & LYPLG_TYPE_STORE_ONLY)) {
505+
/* we tried to find the actual type by validating the value but no type matched, so try to find any type */
506+
ly_err_free(*err);
507+
*err = NULL;
508+
ret = union_find_type(ctx, type_u, subvalue, options, 0, NULL, NULL, NULL, NULL, unres, err);
509+
}
510+
LY_CHECK_GOTO(ret && (ret != LY_EINCOMPLETE), cleanup);
504511
}
505512

506513
/* store canonical value, if any (use the specific type value) */

tests/utests/types/union.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,61 @@ test_validation(void **state)
301301
lyd_free_all(tree);
302302
}
303303

304+
static void
305+
test_validation_store_only(void **state)
306+
{
307+
const char *val_text = NULL;
308+
struct ly_err_item *err = NULL;
309+
struct lys_module *mod;
310+
struct lyd_value value = {0};
311+
struct lyplg_type *type = lysc_get_type_plugin(lyplg_type_plugin_find(NULL, "", NULL, ly_data_type2str[LY_TYPE_UNION]));
312+
struct lysc_type *lysc_type;
313+
const char *schema;
314+
315+
schema = MODULE_CREATE_YANG("base",
316+
"leaf l1 {\n"
317+
" type union {\n"
318+
" type string {\n"
319+
" pattern \"[A-Z]\";\n"
320+
" }\n"
321+
" type int8 {\n"
322+
" range 1..5;\n"
323+
" }\n"
324+
" }\n"
325+
"}\n");
326+
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
327+
lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
328+
329+
/* check proper type */
330+
assert_string_equal("ly2 union", type->id);
331+
332+
/* with LYPLG_TYPE_STORE_ONLY and correct validation */
333+
err = NULL;
334+
val_text = "1";
335+
assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text) * 8,
336+
LYPLG_TYPE_STORE_ONLY, LY_VALUE_XML, mod->parsed, LYD_VALHINT_STRING | LYD_VALHINT_DECNUM, NULL, NULL, &value, NULL, &err));
337+
assert_int_equal(value.subvalue->value.realtype->basetype, LY_TYPE_INT8);
338+
type->free(UTEST_LYCTX, &value);
339+
ly_err_free(err);
340+
341+
/* with LYPLG_TYPE_STORE_ONLY and incorrect validation */
342+
err = NULL;
343+
val_text = "6";
344+
assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text) * 8,
345+
LYPLG_TYPE_STORE_ONLY, LY_VALUE_XML, mod->parsed, LYD_VALHINT_STRING | LYD_VALHINT_DECNUM, NULL, NULL, &value, NULL, &err));
346+
assert_int_equal(value.subvalue->value.realtype->basetype, LY_TYPE_STRING);
347+
type->free(UTEST_LYCTX, &value);
348+
ly_err_free(err);
349+
350+
/* without LYPLG_TYPE_STORE_ONLY and incorrect validation */
351+
err = NULL;
352+
val_text = "10";
353+
assert_int_equal(LY_EVALID, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text) * 8,
354+
0, LY_VALUE_XML, mod->parsed, LYD_VALHINT_STRING | LYD_VALHINT_DECNUM, NULL, NULL, &value, NULL, &err));
355+
ly_err_free(err);
356+
UTEST_LOG_CTX_CLEAN;
357+
}
358+
304359
int
305360
main(void)
306361
{
@@ -310,6 +365,7 @@ main(void)
310365
UTEST(test_plugin_lyb),
311366
UTEST(test_plugin_sort),
312367
UTEST(test_validation),
368+
UTEST(test_validation_store_only),
313369
};
314370

315371
return cmocka_run_group_tests(tests, NULL, NULL);

0 commit comments

Comments
 (0)