From b5db852b3acd0934ec3e44e3bdc56aadebb769b2 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 22 Feb 2012 10:39:37 +0100 Subject: [PATCH] [FIX] fields.binary: allow writing base64 unicode string values The fields.binary type allows storing arbitrary byte arrays, but it has been used historically to store base64-encoded versions of the binaries. This was partially related to the way these binary values are serialized when transferred using the standard XML-RPC protocol. With the introduction of JSON-based RPC calls alongside the 6.1 web client, these base64-encoded binaries may now be deserialized as unicode ASCII strings instead of 8-bit strings. That seems like an acceptable behavior and we can simply coerce these unicode strings to bytes strings as we know they will be pure ASCII. Any non-ASCII unicode value for binary field makes no sense and should be passed as a byte string directly. Thanks to Rui Barreiros for providing the final hint in bug 919982 comments that lead to the identification of this bug. lp bug: https://launchpad.net/bugs/899794 fixed bzr revid: odo@openerp.com-20120222093937-quifmtsfc9gaa9ar --- openerp/osv/fields.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 7c1761a..bb654ca 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -364,7 +364,15 @@ class time(_column): class binary(_column): _type = 'binary' _symbol_c = '%s' - _symbol_f = lambda symb: symb and Binary(symb) or None + + # Binary values may be byte strings (python 2.6 byte array), but + # the legacy OpenERP convention is to transfer and store binaries + # as base64-encoded strings. The base64 string may be provided as a + # unicode in some circumstances, hence the str() cast in symbol_f. + # This str coercion will only work for pure ASCII unicode strings, + # on purpose - non base64 data must be passed as a 8bit byte strings. + _symbol_f = lambda symb: symb and Binary(str(symb)) or None + _symbol_set = (_symbol_c, _symbol_f) _symbol_get = lambda self, x: x and str(x) -- 1.7.10.4