[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Further workarounds for the broken string marshalling in xmlrpclib. Regardless



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 09967f2d6e3b818c3eb79bbe006f95e675acf711
# Parent  395e57314710c0c8d21e3ebc695f17ef6b93709d
Further workarounds for the broken string marshalling in xmlrpclib.  Regardless
of the encoding used, one still may not include non-printable characters in an
XML document.  When a dmesg contains a ^D character, something seen on one of
our test machines, an invalid XML document is generated.

Use a trick by David Mertz to work around this -- escape the string using
Python's repr function.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r 395e57314710 -r 09967f2d6e3b tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Tue Apr  4 10:08:20 2006
+++ b/tools/python/xen/util/xmlrpclib2.py       Wed Apr  5 23:59:06 2006
@@ -20,6 +20,7 @@
 An enhanced XML-RPC client/server interface for Python.
 """
 
+import string
 import types
 
 from httplib import HTTPConnection, HTTP
@@ -54,6 +55,18 @@
     def make_connection(self, host):
         return HTTPUnix(self.__handler)
 
+
+# See _marshalled_dispatch below.
+def conv_string(x):
+    if (isinstance(x, types.StringType) or
+        isinstance(x, unicode)):
+        s = string.replace(x, "'", r"\047")
+        exec "s = '" + s + "'"
+        return s
+    else:
+        return x
+
+
 class ServerProxy(xmlrpclib.ServerProxy):
     def __init__(self, uri, transport=None, encoding=None, verbose=0,
                  allow_none=1):
@@ -64,6 +77,16 @@
                 transport = UnixTransport()
         xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
                                        verbose, allow_none)
+
+
+    def __request(self, methodname, params):
+        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
+
+        if isinstance(response, tuple):
+            return tuple([conv_string(x) for x in response])
+        else:
+            return conv_string(response)
+
 
 # This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
 # true, and has an improved marshaller that logs and serializes exceptions.
@@ -79,14 +102,17 @@
             else:
                 response = self._dispatch(method, params)
 
-            # Convert strings to unicode strings so that they are escaped
-            # properly by xmlrpclib.  We use latin-1 here, but any
-            # ASCII-compatible scheme would do -- we just care about getting
-            # the bytes across the wire.
-            # Any message handler that actually cares about the charset in
-            # use should be returning Unicode strings.
-            if isinstance(response, types.StringType):
-                response = unicode(response, 'iso-8859-1')
+            # With either Unicode or normal strings, we can only transmit
+            # \t, \n, \r, \u0020-\ud7ff, \ue000-\ufffd, and \u10000-\u10ffff
+            # in an XML document.  xmlrpclib does not escape these values
+            # properly, and then breaks when it comes to parse the document.
+            # To hack around this problem, we use repr here and exec above
+            # to transmit the string using Python encoding.
+            # Thanks to David Mertz <mertz@xxxxxxxxx> for the trick (buried
+            # in xml_pickle.py).
+            if (isinstance(response, types.StringType) or
+                isinstance(response, unicode)):
+                response = repr(response)[1:-1]
 
             response = (response,)
             response = xmlrpclib.dumps(response,

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.