xmlbuilder: Validate root element of object parsexml

Ensure that for example a DeviceDisk is actually passed <disk> XML
This commit is contained in:
Cole Robinson 2019-05-08 13:02:35 -04:00
parent 201dfdb23e
commit 472cfbc2a7
3 changed files with 24 additions and 0 deletions

View File

@ -1435,3 +1435,10 @@ class XMLParseTest(unittest.TestCase):
raise AssertionError("Expected ValueError") raise AssertionError("Expected ValueError")
except ValueError: except ValueError:
pass pass
def testXMLRootValidate(self):
try:
virtinst.DeviceDisk(self.conn, parsexml="<foo/>")
raise AssertionError("Expected parse failure")
except RuntimeError as e:
self.assertTrue("'foo'" in str(e))

View File

@ -107,6 +107,8 @@ class _XMLBase(object):
raise NotImplementedError() raise NotImplementedError()
def _node_has_content(self, node): def _node_has_content(self, node):
raise NotImplementedError() raise NotImplementedError()
def _node_get_name(self, node):
raise NotImplementedError()
def node_clear(self, xpath): def node_clear(self, xpath):
raise NotImplementedError() raise NotImplementedError()
def _sanitize_xml(self, xml): def _sanitize_xml(self, xml):
@ -165,6 +167,14 @@ class _XMLBase(object):
return return
self._node_remove_child(parentnode, childnode) self._node_remove_child(parentnode, childnode)
def validate_root_name(self, expected_root_name):
rootname = self._node_get_name(self._find("."))
if rootname == expected_root_name:
return
raise RuntimeError(
_("XML did not have expected root element name '%s', found '%s'") %
(expected_root_name, rootname))
def _node_set_content(self, xpath, node, setval): def _node_set_content(self, xpath, node, setval):
xpathobj = _XPath(xpath) xpathobj = _XPath(xpath)
if setval is not None: if setval is not None:
@ -342,6 +352,9 @@ class _Libxml2API(_XMLBase):
def _node_has_content(self, node): def _node_has_content(self, node):
return node.type == "element" and (node.children or node.properties) return node.type == "element" and (node.children or node.properties)
def _node_get_name(self, node):
return node.name
def _node_remove_child(self, parentnode, childnode): def _node_remove_child(self, parentnode, childnode):
node = childnode node = childnode

View File

@ -393,6 +393,10 @@ class _XMLState(object):
logging.debug("Error parsing xml=\n%s", parsexml) logging.debug("Error parsing xml=\n%s", parsexml)
raise raise
if not self.is_build:
# Ensure parsexml has the correct root node
self.xmlapi.validate_root_name(self._root_name.split(":")[-1])
def set_relative_object_xpath(self, xpath): def set_relative_object_xpath(self, xpath):
self._relative_object_xpath = xpath or "" self._relative_object_xpath = xpath or ""