Use virXMLNodeGetSubelementList to get the elements to process.
The new approach documents the complexity of the parser, which is
designed to ignore unknown attributes and parse only a single kind of
them after finding the first valid one.
Note that the XML schema doesn't actually allow having multiple
sub-elements, but I'm not sure how that translates to actual configs
present.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/conf/nwfilter_conf.c | 65 +++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 34 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index b7400b553a..e6f7c0f8b7 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2374,10 +2374,8 @@ static virNWFilterRuleDef *
virNWFilterRuleParse(xmlNodePtr node)
{
g_autofree char *statematch = NULL;
- bool found;
- int found_i = 0;
-
- xmlNodePtr cur;
+ g_autofree xmlNodePtr *attrNodes = NULL;
+ size_t nattrNodes = 0;
g_autoptr(virNWFilterRuleDef) ret = NULL;
ret = g_new0(virNWFilterRuleDef, 1);
@@ -2403,43 +2401,42 @@ virNWFilterRuleParse(xmlNodePtr node)
(STREQ(statematch, "0") || STRCASEEQ(statematch, "false")))
ret->flags |= RULE_FLAG_NO_STATEMATCH;
- cur = node->children;
-
- found = false;
-
- while (cur != NULL) {
- if (cur->type == XML_ELEMENT_NODE) {
- size_t i = 0;
- while (1) {
- if (found)
- i = found_i;
-
- if (virXMLNodeNameEqual(cur, virAttr[i].id)) {
+ nattrNodes = virXMLNodeGetSubelementList(node, NULL, &attrNodes);
- found_i = i;
- found = true;
- ret->prtclType = virAttr[i].prtclType;
+ if (nattrNodes > 0) {
+ size_t i;
+ size_t attr;
- if (virNWFilterRuleDetailsParse(cur,
- ret,
- virAttr[i].att) < 0) {
- return NULL;
- }
- if (virNWFilterRuleValidate(ret) < 0)
- return NULL;
+ /* First we look up the type of the first valid element. The rest of
+ * the parsing then only considers elements with same name. */
+ for (i = 0; i < nattrNodes; i++) {
+ for (attr = 0; virAttr[attr].id; attr++) {
+ if (virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id)) {
+ ret->prtclType = virAttr[attr].prtclType;
break;
}
- if (!found) {
- i++;
- if (!virAttr[i].id)
- break;
- } else {
- break;
- }
}
+
+ /* if we've found the first correct element end the search */
+ if (virAttr[attr].id)
+ break;
+ }
+
+ /* parse the correct subelements now */
+ for (i = 0; i < nattrNodes; i++) {
+ /* no valid elements */
+ if (!virAttr[attr].id)
+ break;
+
+ if (!virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id))
+ continue;
+
+ if (virNWFilterRuleDetailsParse(attrNodes[i], ret, virAttr[attr].att) <
0)
+ return NULL;
}
- cur = cur->next;
+ if (virNWFilterRuleValidate(ret) < 0)
+ return NULL;
}
virNWFilterRuleDefFixup(ret);
--
2.40.1