Skip to content

Commit 311fe05

Browse files
committed
instid BUGFIX do not compile path for schema default values
Because it causes issues when freeing the modules, depending on the order, freed nodes may be accessed.
1 parent 68b9634 commit 311fe05

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

src/plugins_types/instanceid.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,13 @@ lyplg_type_validate_instanceid(const struct ly_ctx *ctx, const struct lysc_type
253253
}
254254

255255
LIBYANG_API_DEF const void *
256-
lyplg_type_print_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lyd_value *value, LY_VALUE_FORMAT format,
256+
lyplg_type_print_instanceid(const struct ly_ctx *ctx, const struct lyd_value *value, LY_VALUE_FORMAT format,
257257
void *prefix_data, ly_bool *dynamic, size_t *value_len)
258258
{
259-
char *ret;
259+
char *ret = NULL;
260+
struct ly_path *p = NULL;
261+
const struct ly_path *target;
262+
struct ly_err_item *err;
260263

261264
if ((format == LY_VALUE_CANON) || (format == LY_VALUE_JSON) || (format == LY_VALUE_LYB)) {
262265
if (dynamic) {
@@ -268,31 +271,64 @@ lyplg_type_print_instanceid(const struct ly_ctx *UNUSED(ctx), const struct lyd_v
268271
return value->_canonical;
269272
}
270273

274+
if (!value->target) {
275+
/* schema default value, compile it first */
276+
if (lyplg_type_lypath_new(ctx, value->_canonical, strlen(value->_canonical), 0, LY_VALUE_JSON, NULL, NULL,
277+
NULL, &p, &err)) {
278+
if (err) {
279+
ly_err_print(ctx, err);
280+
ly_err_free(err);
281+
}
282+
goto cleanup;
283+
}
284+
285+
target = p;
286+
} else {
287+
target = value->target;
288+
}
289+
271290
/* print the value in the specific format */
272-
if (instanceid_path2str(value->target, format, prefix_data, &ret)) {
273-
return NULL;
291+
if (instanceid_path2str(target, format, prefix_data, &ret)) {
292+
goto cleanup;
274293
}
294+
275295
*dynamic = 1;
276296
if (value_len) {
277297
*value_len = strlen(ret);
278298
}
299+
300+
cleanup:
301+
ly_path_free(p);
279302
return ret;
280303
}
281304

282305
LIBYANG_API_DEF LY_ERR
283306
lyplg_type_dup_instanceid(const struct ly_ctx *ctx, const struct lyd_value *original, struct lyd_value *dup)
284307
{
285308
LY_ERR ret;
309+
struct ly_err_item *err;
286310

287311
memset(dup, 0, sizeof *dup);
288312

289313
/* canonical value */
290314
ret = lydict_insert(ctx, original->_canonical, 0, &dup->_canonical);
291315
LY_CHECK_GOTO(ret, error);
292316

293-
/* copy path */
294-
ret = ly_path_dup(ctx, original->target, &dup->target);
295-
LY_CHECK_GOTO(ret, error);
317+
if (!original->target) {
318+
/* schema default value, needs to be compiled */
319+
if (lyplg_type_lypath_new(ctx, original->_canonical, strlen(original->_canonical), 0, LY_VALUE_JSON, NULL, NULL,
320+
NULL, &dup->target, &err)) {
321+
if (err) {
322+
ly_err_print(ctx, err);
323+
ly_err_free(err);
324+
}
325+
goto error;
326+
}
327+
} else {
328+
/* copy path */
329+
ret = ly_path_dup(ctx, original->target, &dup->target);
330+
LY_CHECK_GOTO(ret, error);
331+
}
296332

297333
dup->realtype = original->realtype;
298334
return LY_SUCCESS;

src/schema_compile.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,12 @@ lys_compile_unres_dflt(struct lysc_ctx *ctx, struct lysc_node *node, struct lysc
963963
}
964964

965965
LY_ATOMIC_INC_BARRIER(((struct lysc_type *)storage->realtype)->refcount);
966+
if (storage->realtype->basetype == LY_TYPE_INST) {
967+
/* ly_path includes references to other nodes, in case they are in foreign modules, the context would
968+
* need to be freed in specific order to avoid accessing freed memory, so just avoid storing it */
969+
ly_path_free(storage->target);
970+
storage->target = NULL;
971+
}
966972
return LY_SUCCESS;
967973
}
968974

tests/utests/schema/test_tree_schema_compile.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,8 +1233,7 @@ test_type_instanceid(void **state)
12331233
{
12341234
struct lys_module *mod;
12351235
struct lysc_type *type;
1236-
1237-
// char *str;
1236+
char *str;
12381237

12391238
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;typedef mytype {type instance-identifier {require-instance false;}}"
12401239
"leaf l1 {type instance-identifier {require-instance true;}}"
@@ -1255,14 +1254,14 @@ test_type_instanceid(void **state)
12551254
assert_int_equal(1, ((struct lysc_type_instanceid *)type)->require_instance);
12561255

12571256
/* default value */
1258-
/* TODO needs a new SO for a proper fix; str = "module b1 {namespace urn:b1;prefix b1;"
1257+
str = "module b1 {namespace urn:b1;prefix b1;"
12591258
"leaf l1 {type string;}}";
12601259
ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, str);
12611260
ly_ctx_set_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED);
12621261
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b2 {namespace urn:b2;prefix b2;"
12631262
"import b1 {prefix b1;}"
12641263
"leaf l1 {type instance-identifier; default \"/b1:l1\";}}", LYS_IN_YANG, NULL));
1265-
ly_ctx_set_options(UTEST_LYCTX, 0);*/
1264+
ly_ctx_set_options(UTEST_LYCTX, 0);
12661265

12671266
/* invalid cases */
12681267
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module aa {namespace urn:aa;prefix aa; leaf l {type instance-identifier {require-instance yes;}}}", LYS_IN_YANG, NULL));

0 commit comments

Comments
 (0)