diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b88afbc4e8..2569c6780f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3645,59 +3645,6 @@ virDomainDefRejectDuplicatePanics(virDomainDefPtr def) return 0; } -/** - * virDomainDefMetadataSanitize: - * @def: Sanitize metadata for this def - * - * This function removes metadata elements in @def that share the namespace. - * The first metadata entry of every duplicate namespace is kept. Additionally - * elements with no namespace are deleted. - */ -static void -virDomainDefMetadataSanitize(virDomainDefPtr def) -{ - xmlNodePtr child; - xmlNodePtr next; - xmlNodePtr dupl; - - if (!def || !def->metadata) - return; - - child = def->metadata->children; - while (child) { - /* remove metadata entries that don't have any namespace at all */ - if (!child->ns || !child->ns->href) { - dupl = child; - child = child->next; - - xmlUnlinkNode(dupl); - xmlFreeNode(dupl); - continue; - } - - /* check that every other child of @root doesn't share the namespace of - * the current one and delete them possibly */ - next = child->next; - while (next) { - dupl = NULL; - - if (child->ns && next->ns && - STREQ_NULLABLE((const char *) child->ns->href, - (const char *) next->ns->href)) - dupl = next; - - next = next->next; - - if (dupl) { - xmlUnlinkNode(dupl); - xmlFreeNode(dupl); - } - } - - child = child->next; - } -} - static int virDomainDefPostParseMemory(virDomainDefPtr def, @@ -4496,7 +4443,7 @@ virDomainDefPostParseInternal(virDomainDefPtr def, } /* clean up possibly duplicated metadata entries */ - virDomainDefMetadataSanitize(def); + virXMLNodeSanitizeNamespaces(def->metadata); virDomainDefPostParseGraphics(def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index de620a853a..04fcb47445 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2602,6 +2602,7 @@ virUUIDParse; # util/virxml.h virXMLChildElementCount; virXMLExtractNamespaceXML; +virXMLNodeSanitizeNamespaces; virXMLNodeToString; virXMLParseHelper; virXMLPickShellSafeComment; diff --git a/src/util/virxml.c b/src/util/virxml.c index aa97940ab7..03bd78437a 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -1083,6 +1083,58 @@ virXMLInjectNamespace(xmlNodePtr node, return 0; } +/** + * virXMLNodeSanitizeNamespaces() + * @node: Sanitize the namespaces for this node + * + * This function removes subnodes in node that share the namespace. + * The first instance of every duplicate namespace is kept. + * Additionally nodes with no namespace are deleted. + */ +void +virXMLNodeSanitizeNamespaces(xmlNodePtr node) +{ + xmlNodePtr child; + xmlNodePtr next; + xmlNodePtr dupl; + + if (!node) + return; + + child = node->children; + while (child) { + /* remove subelements that don't have any namespace at all */ + if (!child->ns || !child->ns->href) { + dupl = child; + child = child->next; + + xmlUnlinkNode(dupl); + xmlFreeNode(dupl); + continue; + } + + /* check that every other child of @root doesn't share the namespace of + * the current one and delete them possibly */ + next = child->next; + while (next) { + dupl = NULL; + + if (child->ns && next->ns && + STREQ_NULLABLE((const char *) child->ns->href, + (const char *) next->ns->href)) + dupl = next; + + next = next->next; + if (dupl) { + xmlUnlinkNode(dupl); + xmlFreeNode(dupl); + } + } + child = child->next; + } +} + + static void catchRNGError(void *ctx, const char *msg, ...) diff --git a/src/util/virxml.h b/src/util/virxml.h index 7a89518b9a..7a0a1dad77 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -179,6 +179,8 @@ int virXMLInjectNamespace(xmlNodePtr node, const char *uri, const char *key); +void virXMLNodeSanitizeNamespaces(xmlNodePtr node); + struct _virXMLValidator { xmlRelaxNGParserCtxtPtr rngParser; xmlRelaxNGPtr rng;