parsers BUGFIX metadata error logging
Fixes #2043
diff --git a/src/parser_json.c b/src/parser_json.c
index 40eb568..701e897 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1236,14 +1236,17 @@
enum LYJSON_PARSER_STATUS *status, struct lyd_node **node)
{
LY_ERR r, rc = LY_SUCCESS;
- uint32_t prev_parse_opts, prev_int_opts;
+ uint32_t prev_parse_opts = lydctx->parse_opts, prev_int_opts = lydctx->int_opts;
struct ly_in in_start;
char *val = NULL;
const char *end;
- struct lyd_node *tree = NULL;
+ struct lyd_node *child = NULL;
+ ly_bool log_node = 0;
assert(snode->nodetype & LYD_NODE_ANY);
+ *node = NULL;
+
/* status check according to allowed JSON types */
if (snode->nodetype == LYS_ANYXML) {
LY_CHECK_RET((*status != LYJSON_OBJECT) && (*status != LYJSON_ARRAY) && (*status != LYJSON_NUMBER) &&
@@ -1256,39 +1259,41 @@
/* create any node */
switch (*status) {
case LYJSON_OBJECT:
+ /* create node */
+ r = lyd_create_any(snode, NULL, LYD_ANYDATA_DATATREE, 1, node);
+ LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+
+ assert(*node);
+ LOG_LOCSET(NULL, *node, NULL, NULL);
+ log_node = 1;
+
/* parse any data tree with correct options, first backup the current options and then make the parser
* process data as opaq nodes */
- prev_parse_opts = lydctx->parse_opts;
lydctx->parse_opts &= ~LYD_PARSE_STRICT;
lydctx->parse_opts |= LYD_PARSE_OPAQ | (ext ? LYD_PARSE_ONLY : 0);
- prev_int_opts = lydctx->int_opts;
lydctx->int_opts |= LYD_INTOPT_ANY | LYD_INTOPT_WITH_SIBLINGS;
lydctx->any_schema = snode;
/* process the anydata content */
do {
- r = lydjson_subtree_r(lydctx, NULL, &tree, NULL);
+ r = lydjson_subtree_r(lydctx, NULL, &child, NULL);
LY_DPARSER_ERR_GOTO(r, rc = r, lydctx, cleanup);
*status = lyjson_ctx_status(lydctx->jsonctx);
} while (*status == LYJSON_OBJECT_NEXT);
- /* restore parser options */
- lydctx->parse_opts = prev_parse_opts;
- lydctx->int_opts = prev_int_opts;
- lydctx->any_schema = NULL;
-
/* finish linking metadata */
- r = lydjson_metadata_finish(lydctx, &tree);
+ r = lydjson_metadata_finish(lydctx, &child);
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
- r = lyd_create_any(snode, tree, LYD_ANYDATA_DATATREE, 1, node);
- LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+ /* assign the data tree */
+ ((struct lyd_node_any *)*node)->value.tree = child;
+ child = NULL;
break;
case LYJSON_ARRAY:
/* skip until the array end */
in_start = *lydctx->jsonctx->in;
- LY_CHECK_RET(lydjson_data_skip(lydctx->jsonctx));
+ LY_CHECK_GOTO(rc = lydjson_data_skip(lydctx->jsonctx), cleanup);
/* return back by all the WS */
end = lydctx->jsonctx->in->current;
@@ -1299,22 +1304,25 @@
/* make a copy of the whole array and store it */
if (asprintf(&val, "[%.*s", (int)(end - in_start.current), in_start.current) == -1) {
LOGMEM(lydctx->jsonctx->ctx);
- return LY_EMEM;
+ rc = LY_EMEM;
+ goto cleanup;
}
r = lyd_create_any(snode, val, LYD_ANYDATA_JSON, 1, node);
- LY_CHECK_ERR_GOTO(r, rc = r, val_err);
+ LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+ val = NULL;
break;
case LYJSON_STRING:
/* string value */
if (lydctx->jsonctx->dynamic) {
- LY_CHECK_RET(lyd_create_any(snode, lydctx->jsonctx->value, LYD_ANYDATA_STRING, 1, node));
+ LY_CHECK_GOTO(rc = lyd_create_any(snode, lydctx->jsonctx->value, LYD_ANYDATA_STRING, 1, node), cleanup);
lydctx->jsonctx->dynamic = 0;
} else {
val = strndup(lydctx->jsonctx->value, lydctx->jsonctx->value_len);
- LY_CHECK_ERR_RET(!val, LOGMEM(lydctx->jsonctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_GOTO(!val, LOGMEM(lydctx->jsonctx->ctx); rc = LY_EMEM, cleanup);
r = lyd_create_any(snode, val, LYD_ANYDATA_STRING, 1, node);
- LY_CHECK_ERR_GOTO(r, rc = r, val_err);
+ LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+ val = NULL;
}
break;
case LYJSON_NUMBER:
@@ -1323,10 +1331,11 @@
/* JSON value */
assert(!lydctx->jsonctx->dynamic);
val = strndup(lydctx->jsonctx->value, lydctx->jsonctx->value_len);
- LY_CHECK_ERR_RET(!val, LOGMEM(lydctx->jsonctx->ctx), LY_EMEM);
+ LY_CHECK_ERR_GOTO(!val, LOGMEM(lydctx->jsonctx->ctx); rc = LY_EMEM, cleanup);
r = lyd_create_any(snode, val, LYD_ANYDATA_JSON, 1, node);
- LY_CHECK_ERR_GOTO(r, rc = r, val_err);
+ LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+ val = NULL;
break;
case LYJSON_NULL:
/* no value */
@@ -1334,14 +1343,20 @@
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
break;
default:
- LOGINT_RET(lydctx->jsonctx->ctx);
+ LOGINT(lydctx->jsonctx->ctx);
+ rc = LY_EINT;
+ goto cleanup;
}
cleanup:
- return rc;
-
-val_err:
+ if (log_node) {
+ LOG_LOCBACK(0, 1, 0, 0);
+ }
+ lydctx->parse_opts = prev_parse_opts;
+ lydctx->int_opts = prev_int_opts;
+ lydctx->any_schema = NULL;
free(val);
+ lyd_free_tree(child);
return rc;
}
diff --git a/src/parser_xml.c b/src/parser_xml.c
index db760b1..506bf18 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -75,6 +75,8 @@
*meta = NULL;
+ LOG_LOCSET(sparent, NULL, NULL, NULL);
+
/* check for NETCONF filter unqualified attributes */
if (!strcmp(sparent->module->name, "notifications")) {
/* ancient module that does not even use the extension */
@@ -163,6 +165,7 @@
}
cleanup:
+ LOG_LOCBACK(1, 0, 0, 0);
if (ret) {
lyd_free_meta_siblings(*meta);
*meta = NULL;
@@ -853,6 +856,7 @@
uint32_t prev_parse_opts = lydctx->parse_opts, prev_int_opts = lydctx->int_opts;
struct lyd_node *child = NULL;
char *val = NULL;
+ ly_bool log_node = 0;
*node = NULL;
@@ -878,6 +882,14 @@
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
val = NULL;
} else {
+ /* create node */
+ r = lyd_create_any(snode, NULL, LYD_ANYDATA_DATATREE, 1, node);
+ LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+
+ assert(*node);
+ LOG_LOCSET(NULL, *node, NULL, NULL);
+ log_node = 1;
+
/* parser next */
r = lyxml_ctx_next(xmlctx);
LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
@@ -893,17 +905,15 @@
LY_DPARSER_ERR_GOTO(r, rc = r, lydctx, cleanup);
}
- /* restore options */
- lydctx->parse_opts = prev_parse_opts;
- lydctx->int_opts = prev_int_opts;
-
- /* create node */
- r = lyd_create_any(snode, child, LYD_ANYDATA_DATATREE, 1, node);
- LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
+ /* assign the data tree */
+ ((struct lyd_node_any *)*node)->value.tree = child;
child = NULL;
}
cleanup:
+ if (log_node) {
+ LOG_LOCBACK(0, 1, 0, 0);
+ }
lydctx->parse_opts = prev_parse_opts;
lydctx->int_opts = prev_int_opts;
free(val);
diff --git a/src/tree_data.c b/src/tree_data.c
index 41e616c..b7617ad 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -2476,7 +2476,8 @@
/* parent */
parent = (depth > 1) ? dnodes->dnodes[depth - 2] : NULL;
- assert(!parent || !iter->schema || !parent->schema || (lysc_data_parent(iter->schema) == parent->schema) ||
+ assert(!parent || !iter->schema || !parent->schema || (parent->schema->nodetype & LYD_NODE_ANY) ||
+ (lysc_data_parent(iter->schema) == parent->schema) ||
(!lysc_data_parent(iter->schema) && (LYD_CTX(iter) != LYD_CTX(parent))));
/* get module to print, if any */
diff --git a/tests/utests/data/test_parser_xml.c b/tests/utests/data/test_parser_xml.c
index 04397ae..01cf7f4 100644
--- a/tests/utests/data/test_parser_xml.c
+++ b/tests/utests/data/test_parser_xml.c
@@ -631,8 +631,33 @@
lyd_free_all(tree);
lyd_free_all(op);
- /* wrong namespace, element name, whatever... */
- /* TODO */
+ /* invalid anyxml nested metadata value */
+ data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\" pid=\"4114692032\">\n"
+ " <copy-config>\n"
+ " <target>\n"
+ " <running/>\n"
+ " </target>\n"
+ " <source>\n"
+ " <config>\n"
+ " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ " <a>val_a</a>\n"
+ " <b>val_b</b>\n"
+ " <c>5</c>\n"
+ " <cont nc:operation=\"merge\">\n"
+ " <e nc:operation=\"merge2\">false</e>\n"
+ " </cont>\n"
+ " </l1>\n"
+ " </config>\n"
+ " </source>\n"
+ " </copy-config>\n"
+ "</rpc>\n";
+ assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
+ assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
+ ly_in_free(in, 0);
+ CHECK_LOG_CTX("Invalid enumeration value \"merge2\".",
+ "Data location \"/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e\", line number 13.");
+ lyd_free_all(tree);
+ assert_null(op);
}
static void