yin parser CHANGE take into account also the namespace of attribute
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 21323bc..3d567da 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -26,6 +26,14 @@
#include "tree_schema_internal.h"
#include "parser_yin.h"
+/**
+ * @brief check if given string is URI of yin namespace.
+ * @param ns Namespace URI to check.
+ *
+ * @return true if ns equals YIN_NS_URI false otherwise.
+ */
+#define IS_YIN_NS(ns) (strcmp(ns, YIN_NS_URI) == 0)
+
const char *const yin_attr_list[] = {
[YIN_ARG_NAME] = "name",
[YIN_ARG_TARGET_NODE] = "target-node",
@@ -108,7 +116,7 @@
}
/**
- * @brief parse yin argument, arg_val is unchanged if argument arg_type wasn't found
+ * @brief parse yin argument, arg_val is unchanged if argument arg_type wasn't found.
*
* @param[in] xml_ctx XML parser context.
* @param[in,out] data Data to read from.
@@ -133,25 +141,31 @@
ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
- arg = match_argument_name(name, name_len);
-
- if (arg == arg_type) {
- LY_CHECK_RET(ret);
- ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
- LY_CHECK_RET(ret);
- *arg_val = lydict_insert(xml_ctx->ctx, out, out_len);
- LY_CHECK_ERR_RET(!(*arg_val), LOGMEM(xml_ctx->ctx), LY_EMEM);
- } else if (arg_type == YIN_ARG_NONE) {
- continue;
- } else {
- /* unrecognized or unexpected attribute */
- if (name) {
- if (arg_type != YIN_ARG_NONE) {
- LOGERR(xml_ctx->ctx, LYVE_SYNTAX_YIN, "Invalid attribute \"%.*s\", expected \"%s\".", name, name_len, yin_attr2str(arg_type));
- } else {
- LOGERR(xml_ctx->ctx, LYVE_SYNTAX_YIN, "Unexpected attribute \"%.*s\".", name_len, name);
+ const struct lyxml_ns *ns = lyxml_ns_get(xml_ctx, prefix, prefix_len);
+ /*
+ * check if loaded attribute is from YIN namespace and if it's of expected type
+ * attributes from different namespaces are silently ignored
+ */
+ if (ns && IS_YIN_NS(ns->uri)) {
+ arg = match_argument_name(name, name_len);
+ if (arg == arg_type) {
+ LY_CHECK_RET(ret);
+ ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
+ LY_CHECK_RET(ret);
+ *arg_val = lydict_insert(xml_ctx->ctx, out, out_len);
+ LY_CHECK_ERR_RET(!(*arg_val), LOGMEM(xml_ctx->ctx), LY_EMEM);
+ } else if (arg_type == YIN_ARG_NONE) {
+ continue;
+ } else {
+ /* unrecognized or unexpected attribute */
+ if (name) {
+ if (arg_type != YIN_ARG_NONE) {
+ LOGERR(xml_ctx->ctx, LYVE_SYNTAX_YIN, "Invalid attribute \"%.*s\", expected \"%s\".", name, name_len, yin_attr2str(arg_type));
+ } else {
+ LOGERR(xml_ctx->ctx, LYVE_SYNTAX_YIN, "Unexpected attribute \"%.*s\".", name_len, name);
+ }
+ return LY_EVALID;
}
- return LY_EVALID;
}
}
}
@@ -191,14 +205,14 @@
}
/**
- * @brief Parse revision date
+ * @brief Parse revision date.
*
* @param[in] xml_ctx Xml context.
* @param[in,out] data Data to read from.
* @param[in,out] rev Array to store the parsed value in.
* @param[in,out] exts Extension instances to add to.
*
- * @return LY_ERR values
+ * @return LY_ERR values.
*/
static LY_ERR
yin_parse_revision_date(struct lyxml_context *xml_ctx, const char **data, char *rev, struct lysp_ext_instance **exts)
@@ -274,7 +288,7 @@
*
* @param[in] xml_ctx xml context.
* @param[in,out] data Data to read from.
- * @param[out] mod Parsed module structure
+ * @param[out] mod Parsed module structure.
*
* @return LY_ERR values.
*/
@@ -286,49 +300,14 @@
const char *prefix, *name;
size_t prefix_len, name_len;
enum yang_module_stmt mod_stmt = Y_MOD_MODULE_HEADER;
- enum YIN_ARGUMENT arg = YIN_ARG_UNKNOWN;
char *buf = NULL, *out = NULL;
size_t buf_len = 0, out_len = 0;
int dynamic;
- /* parse module attributes */
- while (xml_ctx->status == LYXML_ATTRIBUTE) {
- ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
+ yin_parse_attribute(xml_ctx, data, YIN_ARG_NAME, &(*mod)->mod->name);
- arg = match_argument_name(name, name_len);
-
- switch (arg) {
- case YIN_ARG_NAME:
- /* check for multiple definitions of name */
- LY_CHECK_ERR_RET((*mod)->mod->name, LOGVAL_YANG(xml_ctx, LYVE_SYNTAX_YIN, "Duplicit definition of module name \"%s\"",
- (*mod)->mod->name), LY_EEXIST);
-
- /* read module name */
- if (xml_ctx->status != LYXML_ATTR_CONTENT) {
- LOGVAL(xml_ctx->ctx, LY_VLOG_LINE, &xml_ctx->line, LYVE_SYNTAX, "Missing value of argument \"name\".");
- }
- ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
- LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
- (*mod)->mod->name = lydict_insert(xml_ctx->ctx, out, out_len);
- LY_CHECK_ERR_RET(!(*mod)->mod->name, LOGMEM(xml_ctx->ctx), LY_EMEM);
- break;
-
- default:
- /* unrecognized or unexpected attribute */
- /* TODO probably still can be from extension */
- if (arg != YIN_ARG_UNKNOWN || name) {
- LOGERR(xml_ctx->ctx, LY_EDENIED, "Invalid argument in module element");
- return LY_EVALID;
- }
-
- break;
- }
- }
-
- LY_CHECK_ERR_RET(!(*mod)->mod->name, LOGVAL_YANG(xml_ctx, LYVE_SYNTAX_YIN, "Missing argument name of a module", (*mod)->mod->name), LY_EVALID);
-
+ LY_CHECK_ERR_RET(!(*mod)->mod->name, LOGVAL_YANG(xml_ctx, LYVE_SYNTAX_YIN, "Missing argument name of a module"), LY_EVALID);
ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
LY_CHECK_ERR_RET(ret != LY_EINVAL, LOGVAL_YANG(xml_ctx, LYVE_SYNTAX_YIN, "Expected new xml element after module element."), LY_EINVAL);
diff --git a/src/parser_yin.h b/src/parser_yin.h
index 8a2468d..b39f3f3 100644
--- a/src/parser_yin.h
+++ b/src/parser_yin.h
@@ -25,6 +25,8 @@
extern const char *const yin_attr_list[];
#define yin_attr2str(STMT) yin_attr_list[STMT]
+#define YIN_NS_URI "urn:ietf:params:xml:ns:yang:yin:1"
+
enum YIN_ARGUMENT {
YIN_ARG_UNKNOWN = 0, /**< parsed argument can not be matched with any known yin argument keyword */
YIN_ARG_NAME, /**< argument name */
@@ -57,19 +59,19 @@
* @param[in,out] data Data to read from.
* @param[out] value Where content of element should be stored.
*
- * @return LY_ERR values
+ * @return LY_ERR values.
*/
LY_ERR parse_text_element(struct lyxml_context *xml_ctx, const char **data, const char **value);
/**
- * @brief Parse import element
+ * @brief Parse import element.
*
* @param[in] xml_ctx Xml context.
* @param[in] module_prefix Prefix of the module to check prefix collisions.
* @param[in,out] data Dta to read from.
* @param[in,out] imports Parsed imports to add to.
*
- * @return LY_ERR values
+ * @return LY_ERR values.
*/
LY_ERR yin_parse_import(struct lyxml_context *xml_ctx, const char *module_prefix, const char **data, struct lysp_import **imports);
diff --git a/tests/src/test_parser_yin.c b/tests/src/test_parser_yin.c
index d31ef4a..08277af 100644
--- a/tests/src/test_parser_yin.c
+++ b/tests/src/test_parser_yin.c
@@ -147,7 +147,8 @@
struct state *st = *state;
ret = yin_parse_module(st->ctx,
- "<module name=\"example-foo\"\
+ "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
+ name=\"example-foo\"\
xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
xmlns:foo=\"urn:example:foo\"\
xmlns:myext=\"urn:example:extensions\">\
@@ -163,17 +164,17 @@
st = reset_state(state);
ret = yin_parse_module(st->ctx,
- "<module name=\"example-foo\">\
- <invalid-tag uri=\"urn:example:foo\"\"/>\
- </module>",
- st->mod);
+ "<module name=\"example-foo\">\
+ <invalid-tag uri=\"urn:example:foo\"\"/>\
+ </module>",
+ st->mod);
assert_int_equal(ret, LY_EVALID);
st = reset_state(state);
ret = yin_parse_module(st->ctx,
- "<module>\
- </module>",
- st->mod);
+ "<module>\
+ </module>",
+ st->mod);
assert_int_equal(ret, LY_EVALID);
logbuf_assert("Missing argument name of a module Line number 1.");
@@ -288,7 +289,8 @@
LY_ERR ret = LY_SUCCESS;
struct state *st = *state;
- ret = yin_parse_module(st->ctx,"<module name=\"example-foo\">\
+ ret = yin_parse_module(st->ctx,"<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
+ name=\"example-foo\">\
<organization xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">organization...</organization>\
<contact>contact...</contact>\
<description>description...</description>\
@@ -347,12 +349,12 @@
LY_ERR ret = LY_SUCCESS;
struct lysp_import *imports = NULL;
- const char *data = "<import module=\"a\">\
+ const char *data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
<prefix value=\"a_mod\"/>\
<revision-date date=\"2015-01-01\"/>\
</import>\
\
- <import module=\"a\">\
+ <import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
<prefix value=\"a_mod\"/>\
<revision-date date=\"2015-01-01\"/>\
</import>";