]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add support for special char in volume metadata
authorRyan McNair <rdmcnair@us.ibm.com>
Mon, 27 Jan 2014 21:48:51 +0000 (21:48 +0000)
committerRyan McNair <rdmcnair@us.ibm.com>
Thu, 30 Jan 2014 20:01:13 +0000 (20:01 +0000)
Using special characters such as "&" in volume metadata caused SAX
parser to split text into multiple child nodes, as stated in the
specs for SAX parsers. In this case extract_text would return
'None' because text was return if there was exactly
one child node. Concatenating the values of child nodes accounts
for SAX parsers splitting contigous characters into
multiple chunks.

Change-Id: I3709789d33ff7b07eaeaf725f5183105443d0abc
Closes-Bug: #1268513

cinder/api/openstack/wsgi.py
cinder/tests/api/openstack/test_wsgi.py

index e561b7cabef757c9867f79e12b43cc7cfb2a1fba..b1138cdb60c9be974cfa00be86f0f0f9b71aeb01 100644 (file)
@@ -290,11 +290,13 @@ class XMLDeserializer(TextDeserializer):
 
     def extract_text(self, node):
         """Get the text field contained by the given node."""
-        if len(node.childNodes) == 1:
-            child = node.childNodes[0]
+        text = []
+        # Cannot assume entire text will be in a single child node because SAX
+        # parsers may split contiguous character data into multiple chunks
+        for child in node.childNodes:
             if child.nodeType == child.TEXT_NODE:
-                return child.nodeValue
-        return ""
+                text.append(child.nodeValue)
+        return ''.join(text)
 
     def find_attribute_or_element(self, parent, name):
         """Get an attribute value; fallback to an element if not found."""
index 4f8c9144f28ed400dd977b6dbdabce2e140778cf..fe7a4404e0b1b222c68a658d492f6be86a219edc 100644 (file)
@@ -245,6 +245,29 @@ class XMLDeserializerTest(test.TestCase):
         self.assertEqual(deserializer.deserialize(xml), as_dict)
 
 
+class MetadataXMLDeserializerTest(test.TestCase):
+    def test_xml_meta_parsing_special_character(self):
+        """Test that when a SaxParser splits a string containing special
+        characters into multiple childNodes there are no issues extracting
+        the text.
+        """
+        meta_xml_str = """
+            <metadata>
+                <meta key="key3">value&amp;3</meta>
+                <meta key="key2">value2</meta>
+                <meta key="key1">value1</meta>
+            </metadata>
+            """.strip()
+        meta_expected = {'key1': 'value1',
+                         'key2': 'value2',
+                         'key3': 'value&3'}
+        meta_deserializer = wsgi.MetadataXMLDeserializer()
+        document = wsgi.utils.safe_minidom_parse_string(meta_xml_str)
+        root_node = document.childNodes[0]
+        meta_extracted = meta_deserializer.extract_metadata(root_node)
+        self.assertEqual(meta_expected, meta_extracted)
+
+
 class ResourceTest(test.TestCase):
     def test_resource_call(self):
         class Controller(object):