[FIX] base: XML-RPC serialization error on HTML fields (bis)

odoo/odoo#74678 fixed the universal traceback which would happen any
time an HTML field would be read, however it's incomplete because:

* it was tested on a field which wasn't HTML in 14.4
* and no markup was put in the field anyway

So the markup being embedded in the XML-RPC document unescaped was
missed, leading to:

* corrupted (partial) responses when the HTML content is XML-valid,
  depending on the exact API of the client it might only return the
  first or last text segment, or all the text without markup, or
  something else
* outright deserialisation error on XML-invalid content (e.g. void
  elements like <br>)

The cause being that `Markup` overrides all `str` methods to first
escape their parameters before actually applying on the object. This
means `xmlrpc.client.escape` would basically do nothing, then would
concatenate the `Markup` into the document (stringifying it) and send
the entire thing on its way.

Fixes #74884

closes odoo/odoo#74957

X-original-commit: 8a0f7d820cb2296f410be215ffeadd1cefae174c
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2021-08-11 09:07:55 +00:00
parent 5996e2003d
commit f1f0a60643
2 changed files with 10 additions and 4 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ class OdooMarshaller(xmlrpc.client.Marshaller):
dispatch[lazy] = dump_lazy
dispatch[Command] = dispatch[int]
dispatch[Markup] = dispatch[str]
dispatch[Markup] = lambda self, value, write: self.dispatch[str](self, str(value), write)
# monkey-patch xmlrpc.client's marshaller
+9 -3
View File
@@ -52,9 +52,15 @@ class TestXMLRPC(common.HttpCase):
)
def test_xmlrpc_html_field(self):
pid = self.xmlrpc('res.partner', 'create', {'name': 'bob', 'comment': 'sucks'})
[p] = self.xmlrpc('res.partner', 'read', pid, ['comment'])
self.assertEqual(p['comment'], 'sucks')
sig = '<p>bork bork bork <span style="font-weight: bork">bork</span><br></p>'
r = self.env['res.users'].create({
'name': 'bob',
'login': 'bob',
'signature': sig
})
self.assertEqual(str(r.signature), sig)
[x] = self.xmlrpc('res.users', 'read', r.id, ['signature'])
self.assertEqual(x['signature'], sig)
def test_jsonrpc_read_group(self):
self._json_call(