data types BUGFIX resolving derived boolean/empty types
In case of instantiating boolean or empty typedef (not directly these
base types), the type was incorrectly compiled resulting in accessing
freed memory.
Fixes #1042
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 3e0cc12..3199c58 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -3383,7 +3383,7 @@
++(*type)->refcount;
ret = lys_compile_type_(ctx, context_node_p, context_flags, context_mod, context_name, type_p, ctx->mod_def, basetype, NULL, base, type);
LY_CHECK_GOTO(ret, cleanup);
- } else {
+ } else if (basetype != LY_TYPE_BOOL && basetype != LY_TYPE_EMPTY) {
/* no specific restriction in leaf's type definition, copy from the base */
free(*type);
(*type) = base;
diff --git a/tests/features/test_types.c b/tests/features/test_types.c
index 2e9ec85..0b05d9d 100644
--- a/tests/features/test_types.c
+++ b/tests/features/test_types.c
@@ -60,6 +60,8 @@
"identity crypto-alg; identity interface-type; identity ethernet {base interface-type;} identity fast-ethernet {base ethernet;}}";
const char *schema_b = "module types {namespace urn:tests:types;prefix t;yang-version 1.1; import defs {prefix defs;}"
"feature f; identity gigabit-ethernet { base defs:ethernet;}"
+ "typedef tboolean {type boolean;}"
+ "typedef tempty {type empty;}"
"container cont {leaf leaftarget {type empty;}"
"list listtarget {key id; max-elements 5;leaf id {type uint8;} leaf value {type string;}}"
"leaf-list leaflisttarget {type uint8; max-elements 5;}}"
@@ -86,7 +88,9 @@
"leaf str-norestr {type string;}"
"leaf str-utf8 {type string{length 2..5; pattern '€*';}}"
"leaf bool {type boolean;}"
+ "leaf tbool {type tboolean;}"
"leaf empty {type empty;}"
+ "leaf tempty {type tempty;}"
"leaf ident {type identityref {base defs:interface-type;}}"
"leaf inst {type instance-identifier {require-instance true;}}"
"leaf inst-noreq {type instance-identifier {require-instance false;}}"
@@ -639,6 +643,15 @@
assert_int_equal(0, leaf->value.boolean);
lyd_free_all(tree);
+ data = "<tbool xmlns=\"urn:tests:types\">false</tbool>";
+ assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
+ assert_int_equal(LYS_LEAF, tree->schema->nodetype);
+ assert_string_equal("tbool", tree->schema->name);
+ leaf = (struct lyd_node_term*)tree;
+ assert_string_equal("false", leaf->value.canonical_cache);
+ assert_int_equal(0, leaf->value.boolean);
+ lyd_free_all(tree);
+
/* invalid value */
data = "<bool xmlns=\"urn:tests:types\">unsure</bool>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
@@ -678,6 +691,14 @@
assert_string_equal("", leaf->value.canonical_cache);
lyd_free_all(tree);
+ data = "<tempty xmlns=\"urn:tests:types\"/>";
+ assert_non_null(tree = lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));
+ assert_int_equal(LYS_LEAF, tree->schema->nodetype);
+ assert_string_equal("tempty", tree->schema->name);
+ leaf = (struct lyd_node_term*)tree;
+ assert_string_equal("", leaf->value.canonical_cache);
+ lyd_free_all(tree);
+
/* invalid value */
data = "<empty xmlns=\"urn:tests:types\">x</empty>";
assert_null(lyd_parse_mem(s->ctx, data, LYD_XML, LYD_VALOPT_DATA_ONLY));