schema tree BUGFIX check grouping children with respect to uses parent
diff --git a/src/tree_schema.c b/src/tree_schema.c
index ad0dd4a..f4571a1 100755
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -755,7 +755,7 @@
lys_node_addchild(struct lys_node *parent, struct lys_module *module, struct lys_node *child, int options)
{
struct ly_ctx *ctx = child->module->ctx;
- struct lys_node *iter, **pchild;
+ struct lys_node *iter, **pchild, *log_parent;
struct lys_node_inout *in, *out;
struct lys_node_case *c;
int type, shortcase = 0;
@@ -767,10 +767,25 @@
if (parent) {
type = parent->nodetype;
module = parent->module;
+ log_parent = parent;
+
+ if (type == LYS_USES) {
+ /* we are adding children to uses -> we must be copying grouping contents into it, so properly check the parent */
+ log_parent = lys_parent(log_parent);
+ while (log_parent && (log_parent->nodetype == LYS_USES)) {
+ log_parent = lys_parent(log_parent);
+ }
+ if (log_parent) {
+ type = log_parent->nodetype;
+ } else {
+ type = 0;
+ }
+ }
} else {
assert(module);
assert(!(child->nodetype & (LYS_INPUT | LYS_OUTPUT)));
type = 0;
+ log_parent = NULL;
}
/* checks */
@@ -782,7 +797,7 @@
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_GROUPING | LYS_LEAF |
LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ACTION | LYS_NOTIF))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
return EXIT_FAILURE;
}
break;
@@ -792,14 +807,14 @@
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_GROUPING | LYS_LEAF |
LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
return EXIT_FAILURE;
}
break;
case LYS_CHOICE:
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CASE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_CHOICE))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "choice");
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "choice");
return EXIT_FAILURE;
}
if (child->nodetype != LYS_CASE) {
@@ -809,14 +824,14 @@
case LYS_CASE:
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_USES))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "case");
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "case");
return EXIT_FAILURE;
}
break;
case LYS_RPC:
case LYS_ACTION:
if (!(child->nodetype & (LYS_INPUT | LYS_OUTPUT | LYS_GROUPING))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "rpc");
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "rpc");
return EXIT_FAILURE;
}
break;
@@ -824,15 +839,15 @@
case LYS_LEAFLIST:
case LYS_ANYXML:
case LYS_ANYDATA:
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
LOGVAL(ctx, LYE_SPEC, LY_VLOG_PREV, NULL, "The \"%s\" statement cannot have any data substatement.",
- strnodetype(parent->nodetype));
+ strnodetype(log_parent->nodetype));
return EXIT_FAILURE;
case LYS_AUGMENT:
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CASE | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF
| LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_ACTION | LYS_NOTIF))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), strnodetype(parent->nodetype));
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), strnodetype(log_parent->nodetype));
return EXIT_FAILURE;
}
break;
@@ -841,16 +856,16 @@
if (!(child->nodetype &
(LYS_ANYDATA | LYS_CHOICE | LYS_CONTAINER | LYS_LEAF | LYS_GROUPING
| LYS_LEAFLIST | LYS_LIST | LYS_USES | LYS_RPC | LYS_NOTIF | LYS_AUGMENT))) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype), "(sub)module");
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype), "(sub)module");
return EXIT_FAILURE;
}
break;
case LYS_EXT:
/* plugin-defined */
- p = lys_ext_complex_get_substmt(lys_snode2stmt(child->nodetype), (struct lys_ext_instance_complex*)parent, &info);
+ p = lys_ext_complex_get_substmt(lys_snode2stmt(child->nodetype), (struct lys_ext_instance_complex*)log_parent, &info);
if (!p) {
- LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, parent, strnodetype(child->nodetype),
- ((struct lys_ext_instance_complex*)parent)->def->name);
+ LOGVAL(ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, log_parent, strnodetype(child->nodetype),
+ ((struct lys_ext_instance_complex*)log_parent)->def->name);
return EXIT_FAILURE;
}
/* TODO check cardinality */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e2e9b77..6c37978 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,7 +9,7 @@
set(api_tests test_libyang test_tree_schema test_xml test_dict test_tree_data test_tree_data_dup test_tree_data_merge test_xpath test_xpath_1.1 test_diff)
set(data_tests test_data_initialization test_leafref_remove test_instid_remove test_keys test_autodel test_when test_when_1.1 test_must_1.1 test_defaults test_emptycont test_unique test_mandatory test_json test_parse_print test_values test_metadata test_yangtypes_xpath test_yang_data test_unknown_element)
set(schema_yin_tests test_print_transform)
-set(schema_tests test_ietf test_augment test_deviation test_refine test_typedef test_import test_include test_feature test_conformance test_leaflist test_status test_printer)
+set(schema_tests test_ietf test_augment test_deviation test_refine test_typedef test_import test_include test_feature test_conformance test_leaflist test_status test_printer test_invalid)
if(CMAKE_BUILD_TYPE MATCHES debug)
list(APPEND schema_tests test_extensions)
endif(CMAKE_BUILD_TYPE MATCHES debug)
diff --git a/tests/schema/test_invalid.c b/tests/schema/test_invalid.c
new file mode 100644
index 0000000..7c02d2c
--- /dev/null
+++ b/tests/schema/test_invalid.c
@@ -0,0 +1,93 @@
+/**
+ * \file test_invalid.c
+ * \author Michal Vasko <mvasko@cesnet.cz>
+ * \brief libyang tests - loading invalid schemas
+ *
+ * Copyright (c) 2018 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <setjmp.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <cmocka.h>
+
+#include "libyang.h"
+#include "tests/config.h"
+
+struct state {
+ struct ly_ctx *ctx;
+};
+
+static int
+setup_ctx(void **state)
+{
+ struct state *st;
+ (*state) = st = calloc(1, sizeof *st);
+ if (!st) {
+ fprintf(stderr, "Memory allocation error");
+ return -1;
+ }
+
+ /* libyang context */
+ st->ctx = ly_ctx_new(NULL, 0);
+ if (!st->ctx) {
+ fprintf(stderr, "Failed to create context.\n");
+ goto error;
+ }
+
+ return 0;
+
+error:
+ ly_ctx_destroy(st->ctx, NULL);
+ free(st);
+ (*state) = NULL;
+
+ return -1;
+}
+
+static int
+teardown_ctx(void **state)
+{
+ struct state *st = (*state);
+
+ ly_ctx_destroy(st->ctx, NULL);
+ free(st);
+ (*state) = NULL;
+
+ return 0;
+}
+
+static void
+test_case_act_notif(void **state)
+{
+ const char *schema = TESTS_DIR"/schema/yang/files/case-act-notif.yang";
+ struct state *st = (*state);
+ const struct lys_module *mod;
+
+ mod = lys_parse_path(st->ctx, schema, LYS_IN_YANG);
+ assert_ptr_equal(mod, NULL);
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest cmut[] = {
+ cmocka_unit_test_setup_teardown(test_case_act_notif, setup_ctx, teardown_ctx),
+ };
+
+ return cmocka_run_group_tests(cmut, NULL, NULL);
+}
diff --git a/tests/schema/yang/files/case-act-notif.yang b/tests/schema/yang/files/case-act-notif.yang
new file mode 100644
index 0000000..cc4dcf2
--- /dev/null
+++ b/tests/schema/yang/files/case-act-notif.yang
@@ -0,0 +1,23 @@
+module case-act-notif {
+ yang-version 1.1;
+ namespace uri:test:case-act-notif;
+ prefix can;
+
+ choice c {
+ case a {
+ leaf aa {
+ type empty;
+ }
+ uses g1;
+ uses g2;
+ }
+ }
+
+ grouping g1 {
+ action act;
+ }
+
+ grouping g2 {
+ notification notif;
+ }
+}