XML parser CHANGE allow empty leaf when it is deleted in edit-config
In edit-config, when a leaf is being deleted (it has attribute operation
in NETCONF base namespace and its value is 'delete' or 'remove'), it
is allowed to have no value even in case the data type does not allow
empty value. In such a case, the leaf is going to be deleted despite
the current value of the leaf in the target data tree.
Note, that this behaviour is possible only for leafs.
Fixes #130
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 7bf37e3..f1bd781 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -75,7 +75,7 @@
/* logs directly */
static int
-xml_get_value(struct lyd_node *node, struct lyxml_elem *xml, int options)
+xml_get_value(struct lyd_node *node, struct lyxml_elem *xml, int options, int editbits)
{
struct lyd_node_leaf_list *leaf = (struct lyd_node_leaf_list *)node;
int resolve;
@@ -94,6 +94,13 @@
resolve = 1;
}
+ if ((editbits & 0x10) && (node->schema->nodetype & LYS_LEAF) && (!leaf->value_str || !leaf->value_str[0])) {
+ /* we have edit-config leaf/leaf-list with delete operation and no (empty) value,
+ * this is not a bug since the node is just used as a kind of selection node */
+ leaf->value_type = LY_TYPE_ERR;
+ return EXIT_SUCCESS;
+ }
+
if ((leaf->value_type == LY_TYPE_IDENT) || (leaf->value_type == LY_TYPE_INST)) {
/* convert the path from the XML form using XML namespaces into the JSON format
* using module names as namespaces
@@ -126,7 +133,7 @@
struct lyd_attr *dattr, *dattr_iter;
struct lyxml_attr *attr;
struct lyxml_elem *child, *next;
- int i, j, havechildren, r, flag, pos;
+ int i, j, havechildren, r, flag, pos, editbits = 0;
int ret = 0;
const char *str = NULL;
@@ -299,7 +306,6 @@
* 0x08 - key attribute present
* 0x10 - operation not allowing insert attribute
*/
- i = 0;
for (attr = xml->attr; attr; attr = attr->next) {
if (attr->type != LYXML_ATTR_STD || !attr->ns) {
/* not interesting attribute or namespace declaration */
@@ -307,13 +313,13 @@
}
if (!strcmp(attr->name, "operation") && !strcmp(attr->ns->value, LY_NSNC)) {
- if (i & 0x10) {
+ if (editbits & 0x10) {
LOGVAL(LYE_TOOMANY, LY_VLOG_LYD, (*result), "operation attributes", xml->name);
return -1;
}
if (!strcmp(attr->value, "delete") || !strcmp(attr->value, "remove")) {
- i |= 0x10;
+ editbits |= 0x10;
} else if (strcmp(attr->value, "create") &&
strcmp(attr->value, "merge") &&
strcmp(attr->value, "replace")) {
@@ -329,49 +335,49 @@
return -1;
}
- if (i & 0x01) {
+ if (editbits & 0x01) {
LOGVAL(LYE_TOOMANY, LY_VLOG_LYD, (*result), "insert attributes", xml->name);
return -1;
}
if (!strcmp(attr->value, "first") || !strcmp(attr->value, "last")) {
- i |= 0x01;
+ editbits |= 0x01;
} else if (!strcmp(attr->value, "before") || !strcmp(attr->value, "after")) {
- i |= 0x01 | 0x02;
+ editbits |= 0x01 | 0x02;
} else {
LOGVAL(LYE_INVALATTR, LY_VLOG_LYD, (*result), attr->value, attr->name);
return -1;
}
str = attr->name;
} else if (!strcmp(attr->name, "value") && !strcmp(attr->ns->value, LY_NSYANG)) {
- if (i & 0x04) {
+ if (editbits & 0x04) {
LOGVAL(LYE_TOOMANY, LY_VLOG_LYD, (*result), "value attributes", xml->name);
return -1;
} else if (schema->nodetype & LYS_LIST) {
LOGVAL(LYE_INATTR, LY_VLOG_LYD, (*result), attr->name, schema->name);
return -1;
}
- i |= 0x04;
+ editbits |= 0x04;
str = attr->name;
} else if (!strcmp(attr->name, "key") && !strcmp(attr->ns->value, LY_NSYANG)) {
- if (i & 0x08) {
+ if (editbits & 0x08) {
LOGVAL(LYE_TOOMANY, LY_VLOG_LYD, (*result), "key attributes", xml->name);
return -1;
} else if (schema->nodetype & LYS_LEAFLIST) {
LOGVAL(LYE_INATTR, LY_VLOG_LYD, (*result), attr->name, schema->name);
return -1;
}
- i |= 0x08;
+ editbits |= 0x08;
str = attr->name;
}
}
/* report errors */
- if (i > 0x10 || (i && i < 0x10 &&
+ if (editbits > 0x10 || (editbits && editbits < 0x10 &&
(!(schema->nodetype & (LYS_LEAFLIST | LYS_LIST)) || !(schema->flags & LYS_USERORDERED)))) {
/* attributes in wrong elements */
LOGVAL(LYE_INATTR, LY_VLOG_LYD, (*result), str, xml->name);
return -1;
- } else if (i == 3) {
+ } else if (editbits == 3) {
/* 0x01 | 0x02 - relative position, but value/key is missing */
if (schema->nodetype & LYS_LIST) {
LOGVAL(LYE_MISSATTR, LY_VLOG_LYD, (*result), "key", xml->name);
@@ -379,9 +385,9 @@
LOGVAL(LYE_MISSATTR, LY_VLOG_LYD, (*result), "value", xml->name);
}
return -1;
- } else if ((i & (0x04 | 0x08)) && !(i & 0x02)) {
+ } else if ((editbits & (0x04 | 0x08)) && !(editbits & 0x02)) {
/* key/value without relative position */
- LOGVAL(LYE_INATTR, LY_VLOG_LYD, (*result), (i & 0x04) ? "value" : "key", schema->name);
+ LOGVAL(LYE_INATTR, LY_VLOG_LYD, (*result), (editbits & 0x04) ? "value" : "key", schema->name);
return -1;
}
}
@@ -389,7 +395,7 @@
/* type specific processing */
if (schema->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
/* type detection and assigning the value */
- if (xml_get_value(*result, xml, options)) {
+ if (xml_get_value(*result, xml, options, editbits)) {
goto error;
}
} else if (schema->nodetype & LYS_ANYDATA) {