diff --git a/swift/account/utils.py b/swift/account/utils.py index 769169152f..6b18850f78 100644 --- a/swift/account/utils.py +++ b/swift/account/utils.py @@ -98,13 +98,13 @@ def account_listing_response(account, req, response_content_type, broker=None, output_list = ['', '' % saxutils.quoteattr(account)] for (name, object_count, bytes_used, is_subdir) in account_list: - name = saxutils.escape(name) if is_subdir: - output_list.append('' % name) + output_list.append( + '' % saxutils.quoteattr(name)) else: item = '%s%s' \ '%s' % \ - (name, object_count, bytes_used) + (saxutils.escape(name), object_count, bytes_used) output_list.append(item) output_list.append('') account_list = '\n'.join(output_list) diff --git a/swift/container/server.py b/swift/container/server.py index c09fd224e3..763e0e9fb0 100644 --- a/swift/container/server.py +++ b/swift/container/server.py @@ -436,16 +436,15 @@ class ContainerController(object): elif out_content_type.endswith('/xml'): xml_output = [] for (name, created_at, size, content_type, etag) in container_list: - # escape name and format date here - name = saxutils.escape(name) created_at = datetime.utcfromtimestamp( float(created_at)).isoformat() # python isoformat() doesn't include msecs when zero if len(created_at) < len("1970-01-01T00:00:00.000000"): created_at += ".000000" if content_type is None: - xml_output.append('%s' - '' % (name, name)) + xml_output.append( + '%s' % + (saxutils.quoteattr(name), saxutils.escape(name))) else: content_type, size = self.derive_content_type_metadata( content_type, size) @@ -454,7 +453,8 @@ class ContainerController(object): '%s%s' '%d%s' '%s' % - (name, etag, size, content_type, created_at)) + (saxutils.escape(name), etag, size, content_type, + created_at)) container_list = ''.join([ '\n', '' % saxutils.quoteattr(container), diff --git a/test/unit/account/test_server.py b/test/unit/account/test_server.py index 6e3ce17646..22902da825 100644 --- a/test/unit/account/test_server.py +++ b/test/unit/account/test_server.py @@ -676,6 +676,29 @@ class TestAccountController(unittest.TestCase): dom.firstChild.firstChild.nextSibling.firstChild.firstChild.data, '"US-TX-' 'US-UT-') + def test_GET_delimiter_xml_with_quotes(self): + req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT', + 'HTTP_X_TIMESTAMP': '0'}) + resp = self.controller.PUT(req) + req = Request.blank('/sda1/p/a/c/<\'sub\' "dir">/object', + environ={ + 'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '1', + 'HTTP_X_CONTENT_TYPE': 'text/plain', 'HTTP_X_ETAG': 'x', + 'HTTP_X_SIZE': 0}) + resp = self.controller.PUT(req) + self.assertEquals(resp.status_int, 201) + req = Request.blank('/sda1/p/a/c?delimiter=/&format=xml', + environ={'REQUEST_METHOD': 'GET'}) + resp = self.controller.GET(req) + self.assertEquals( + resp.body, + '\n' + '' + '<\'sub\' "dir">/') + def test_GET_path(self): req = Request.blank('/sda1/p/a/c', environ={'REQUEST_METHOD': 'PUT', 'HTTP_X_TIMESTAMP': '0'})