plugins exts BUGFIX proper value conversions
diff --git a/src/plugins_exts.c b/src/plugins_exts.c
index 27ecbdd..a82e009 100644
--- a/src/plugins_exts.c
+++ b/src/plugins_exts.c
@@ -130,7 +130,7 @@
struct lysp_node *pnodes, *pnode;
struct lysc_node *node;
- lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
pnodes = (struct lysp_node *)parsed;
/* compile nodes */
@@ -205,7 +205,7 @@
const struct lysp_when *when = parsed;
/* read compiled status */
- lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
/* compile */
LY_CHECK_GOTO(rc = lys_compile_when(ctx, when, flags, NULL, NULL, NULL, substmt->storage), cleanup);
@@ -261,8 +261,8 @@
const struct lysp_type *ptype = parsed;
/* read compiled info */
- lyplg_ext_get_storage(ext, LY_STMT_STATUS, (const void **)&flags);
- lyplg_ext_get_storage(ext, LY_STMT_UNITS, (const void **)&units);
+ lyplg_ext_get_storage(ext, LY_STMT_STATUS, sizeof flags, (const void **)&flags);
+ lyplg_ext_get_storage(ext, LY_STMT_UNITS, sizeof units, (const void **)&units);
/* compile */
LY_CHECK_GOTO(rc = lys_compile_type(ctx, NULL, flags, ext->def->name, ptype, substmt->storage, &units, NULL), cleanup);
@@ -601,7 +601,7 @@
}
LIBYANG_API_DEF LY_ERR
-lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage)
+lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, uint32_t storage_size, const void **storage)
{
LY_ERR r;
const void **s;
@@ -612,16 +612,35 @@
return r;
}
- *storage = *s;
+ /* matters for little-endian */
+ switch (storage_size) {
+ case 1:
+ *(uint8_t *)storage = (uintptr_t)*s;
+ break;
+ case 2:
+ *(uint16_t *)storage = (uintptr_t)*s;
+ break;
+ case 4:
+ *(uint32_t *)storage = (uintptr_t)*s;
+ break;
+ case 8:
+ *(uint64_t *)storage = (uintptr_t)*s;
+ break;
+ default:
+ LOGERR(ext->module->ctx, LY_EINVAL, "Invalid storage size %" PRIu32 ".", storage_size);
+ return LY_EINVAL;
+ }
+
return LY_SUCCESS;
}
LIBYANG_API_DEF LY_ERR
-lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage)
+lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, uint32_t storage_size, const void **storage)
{
LY_ARRAY_COUNT_TYPE u;
const struct lysp_ext_instance *extp = NULL;
enum ly_stmt match = 0;
+ const void **s = NULL;
*storage = NULL;
@@ -644,11 +663,33 @@
/* get the substatement */
LY_ARRAY_FOR(extp->substmts, u) {
if ((match && (extp->substmts[u].stmt == match)) || (!match && (extp->substmts[u].stmt & stmt))) {
- *storage = *(void **)extp->substmts[u].storage;
- return LY_SUCCESS;
+ s = extp->substmts[u].storage;
+ break;
}
}
+ if (s) {
+ /* matters for little-endian */
+ switch (storage_size) {
+ case 1:
+ *(uint8_t *)storage = (uintptr_t)*s;
+ break;
+ case 2:
+ *(uint16_t *)storage = (uintptr_t)*s;
+ break;
+ case 4:
+ *(uint32_t *)storage = (uintptr_t)*s;
+ break;
+ case 8:
+ *(uint64_t *)storage = (uintptr_t)*s;
+ break;
+ default:
+ LOGERR(ext->module->ctx, LY_EINVAL, "Invalid storage size %" PRIu32 ".", storage_size);
+ return LY_EINVAL;
+ }
+
+ return LY_SUCCESS;
+ }
return LY_ENOT;
}
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index c735488..6355da0 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -946,11 +946,13 @@
* @param[in] ext Compiled ext instance.
* @param[in] stmt Compiled statement. Can be a mask when the first match is returned, it is expected the storage is
* the same for all the masked statements.
+ * @param[in] storage_size Size of the value at @p storage address (dereferenced).
* @param[out] storage Compiled ext instance substatement storage, NULL if was not compiled.
* @return LY_SUCCESS on success.
* @return LY_ENOT if the substatement is not supported.
*/
-LIBYANG_API_DECL LY_ERR lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage);
+LIBYANG_API_DECL LY_ERR lyplg_ext_get_storage(const struct lysc_ext_instance *ext, int stmt, uint32_t storage_size,
+ const void **storage);
/**
* @brief Get parsed ext instance storage for a specific statement.
@@ -958,11 +960,13 @@
* @param[in] ext Compiled ext instance.
* @param[in] stmt Parsed statement. Can be a mask when the first match is returned, it is expected the storage is
* the same for all the masked statements.
+ * @param[in] storage_size Size of the value at @p storage address (dereferenced).
* @param[out] storage Parsed ext instance substatement storage, NULL if was not parsed.
* @return LY_SUCCESS on success.
* @return LY_ENOT if the substatement is not supported.
*/
-LIBYANG_API_DECL LY_ERR lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt, const void **storage);
+LIBYANG_API_DECL LY_ERR lyplg_ext_parsed_get_storage(const struct lysc_ext_instance *ext, int stmt,
+ uint32_t storage_size, const void **storage);
/**
* @brief Get specific run-time extension instance data from a callback set by ::ly_ctx_set_ext_data_clb().
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 43cc202..fa0d2cd 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -3742,7 +3742,7 @@
/* if in an extension, search possible groupings in it */
if (ctx->ext) {
- lyplg_ext_parsed_get_storage(ctx->ext, LY_STMT_GROUPING, (const void **)&ext_grp);
+ lyplg_ext_parsed_get_storage(ctx->ext, LY_STMT_GROUPING, sizeof ext_grp, (const void **)&ext_grp);
if ((grp = match_grouping(ext_grp, name))) {
found = ctx->pmod;
}
diff --git a/src/tree_data.c b/src/tree_data.c
index ceaea54..8704a96 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -977,7 +977,7 @@
LY_CHECK_ERR_GOTO(!mt, LOGMEM(mod->ctx); ret = LY_EMEM, cleanup);
mt->parent = parent;
mt->annotation = ant;
- lyplg_ext_get_storage(ant, LY_STMT_TYPE, (const void **)&ant_type);
+ lyplg_ext_get_storage(ant, LY_STMT_TYPE, sizeof ant_type, (const void **)&ant_type);
ret = lyd_value_store(mod->ctx, &mt->value, ant_type, value, value_len, dynamic, format, prefix_data, hints,
ctx_node, incomplete);
LY_CHECK_ERR_GOTO(ret, free(mt), cleanup);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 3be476d..d225903 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -179,7 +179,7 @@
} else {
/* top level data */
if (ext) {
- lyplg_ext_get_storage(ext, LY_STMT_DATA_NODE_MASK, (const void **)&last);
+ lyplg_ext_get_storage(ext, LY_STMT_DATA_NODE_MASK, sizeof last, (const void **)&last);
next = last;
} else {
next = last = module->data;
@@ -211,7 +211,7 @@
} else if (!action_flag) {
action_flag = 1;
if (ext) {
- lyplg_ext_get_storage(ext, LY_STMT_OP_MASK, (const void **)&next);
+ lyplg_ext_get_storage(ext, LY_STMT_OP_MASK, sizeof next, (const void **)&next);
} else if (parent) {
next = (struct lysc_node *)lysc_node_actions(parent);
} else {
@@ -220,7 +220,7 @@
} else if (!notif_flag) {
notif_flag = 1;
if (ext) {
- lyplg_ext_get_storage(ext, LY_STMT_NOTIFICATION, (const void **)&next);
+ lyplg_ext_get_storage(ext, LY_STMT_NOTIFICATION, sizeof next, (const void **)&next);
} else if (parent) {
next = (struct lysc_node *)lysc_node_notifs(parent);
} else {
diff --git a/src/tree_schema_common.c b/src/tree_schema_common.c
index e82f6b9..d981dbc 100644
--- a/src/tree_schema_common.c
+++ b/src/tree_schema_common.c
@@ -381,7 +381,7 @@
if (ext) {
/* search typedefs directly in the extension */
- lyplg_ext_parsed_get_storage(ext, LY_STMT_TYPEDEF, (const void **)&ext_typedefs);
+ lyplg_ext_parsed_get_storage(ext, LY_STMT_TYPEDEF, sizeof ext_typedefs, (const void **)&ext_typedefs);
if ((*tpdf = lysp_typedef_match(name, ext_typedefs))) {
/* match */
return LY_SUCCESS;
diff --git a/src/validation.c b/src/validation.c
index 8466147..7065cd0 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -348,7 +348,7 @@
struct lysc_type *type;
/* validate and store the value of the metadata */
- lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, (const void **)&type);
+ lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, sizeof type, (const void **)&type);
ret = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
LY_CHECK_RET(ret);
@@ -1541,7 +1541,7 @@
}
LY_LIST_FOR(node->meta, meta) {
- lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, (const void **)&type);
+ lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, sizeof type, (const void **)&type);
if (type->plugin->validate) {
/* metadata type resolution */
LY_CHECK_RET(ly_set_add(meta_types, (void *)meta, 1, NULL));
diff --git a/tests/utests/extensions/test_metadata.c b/tests/utests/extensions/test_metadata.c
index f41a51a..39d29be 100644
--- a/tests/utests/extensions/test_metadata.c
+++ b/tests/utests/extensions/test_metadata.c
@@ -43,7 +43,7 @@
e = &mod->compiled->exts[0];
assert_non_null(e->compiled);
assert_non_null(e->substmts);
- lyplg_ext_get_storage(e, LY_STMT_UNITS, (const void **)&units);
+ lyplg_ext_get_storage(e, LY_STMT_UNITS, sizeof units, (const void **)&units);
assert_string_equal("meters", units);
/* invalid */
@@ -122,7 +122,7 @@
e = &mod->compiled->exts[0];
assert_non_null(e->compiled);
assert_non_null(e->substmts);
- lyplg_ext_get_storage(e, LY_STMT_UNITS, (const void **)&units);
+ lyplg_ext_get_storage(e, LY_STMT_UNITS, sizeof units, (const void **)&units);
assert_string_equal("meters", units);
/* invalid */