virNWFilterRuleParse: Refactor attribute parser

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2023-02-16 13:56:53 +01:00
parent 3774fca88f
commit 59a1455012

View File

@ -2374,10 +2374,8 @@ static virNWFilterRuleDef *
virNWFilterRuleParse(xmlNodePtr node) virNWFilterRuleParse(xmlNodePtr node)
{ {
g_autofree char *statematch = NULL; g_autofree char *statematch = NULL;
bool found; g_autofree xmlNodePtr *attrNodes = NULL;
int found_i = 0; size_t nattrNodes = 0;
xmlNodePtr cur;
g_autoptr(virNWFilterRuleDef) ret = NULL; g_autoptr(virNWFilterRuleDef) ret = NULL;
ret = g_new0(virNWFilterRuleDef, 1); ret = g_new0(virNWFilterRuleDef, 1);
@ -2403,43 +2401,42 @@ virNWFilterRuleParse(xmlNodePtr node)
(STREQ(statematch, "0") || STRCASEEQ(statematch, "false"))) (STREQ(statematch, "0") || STRCASEEQ(statematch, "false")))
ret->flags |= RULE_FLAG_NO_STATEMATCH; ret->flags |= RULE_FLAG_NO_STATEMATCH;
cur = node->children; nattrNodes = virXMLNodeGetSubelementList(node, NULL, &attrNodes);
found = false; if (nattrNodes > 0) {
size_t i;
size_t attr;
while (cur != NULL) { /* First we look up the type of the first valid element. The rest of
if (cur->type == XML_ELEMENT_NODE) { * the parsing then only considers elements with same name. */
size_t i = 0; for (i = 0; i < nattrNodes; i++) {
while (1) { for (attr = 0; virAttr[attr].id; attr++) {
if (found) if (virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id)) {
i = found_i; ret->prtclType = virAttr[attr].prtclType;
break;
}
}
if (virXMLNodeNameEqual(cur, virAttr[i].id)) { /* if we've found the first correct element end the search */
if (virAttr[attr].id)
break;
}
found_i = i; /* parse the correct subelements now */
found = true; for (i = 0; i < nattrNodes; i++) {
ret->prtclType = virAttr[i].prtclType; /* no valid elements */
if (!virAttr[attr].id)
break;
if (virNWFilterRuleDetailsParse(cur, if (!virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id))
ret, continue;
virAttr[i].att) < 0) {
if (virNWFilterRuleDetailsParse(attrNodes[i], ret, virAttr[attr].att) < 0)
return NULL; return NULL;
} }
if (virNWFilterRuleValidate(ret) < 0) if (virNWFilterRuleValidate(ret) < 0)
return NULL; return NULL;
break;
}
if (!found) {
i++;
if (!virAttr[i].id)
break;
} else {
break;
}
}
}
cur = cur->next;
} }
virNWFilterRuleDefFixup(ret); virNWFilterRuleDefFixup(ret);