From 11d521d918e7dcaf185ee28c8d754b2979f3b0ad Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 6 Oct 2020 12:11:48 +0000 Subject: [PATCH] [FIX] core: assignment of size to new records Upon onchange, the web client sends unchanged image fields on one2many lines as "bin size" values, while changed image fields are sent as their full value. As the value is not base64-encoded, the assignment of that value crashes. Fix it by making assignment on new records not crash when decoding the image: the value is simply not assigned to the field. In the situation described above, the record being assigned is a new record with a real record as origin. Because the field is actually not assigned, its value is implicitly the value of the field on the origin record, which is consistent with the fact that the field was not modified in the form. X-original-commit: 4442d6f0f29a2bf6e992515cd535c88215855a36 --- odoo/addons/test_new_api/tests/test_new_fields.py | 9 ++++++++- odoo/fields.py | 13 ++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 10993c52668..441362e7038 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -1953,11 +1953,18 @@ class TestFields(TransactionCaseWithUserDemo): self.assertEqual(image_data_uri(record.image_256)[:30], 'data:image/png;base64,iVBORw0K') # ensure invalid image raises - with self.assertRaises(UserError): + with self.assertRaises(UserError), self.cr.savepoint(): record.write({ 'image': 'invalid image', }) + # assignment of invalid image on new record does nothing, the value is + # taken from origin instead (use-case: onchange) + new_record = record.new(origin=record) + new_record.image = '31.54 Kb' + self.assertEqual(record.image, image_h) + self.assertEqual(new_record.image, image_h) + def test_95_binary_bin_size(self): binary_value = base64.b64encode(b'content') binary_size = b'7.00 bytes' diff --git a/odoo/fields.py b/odoo/fields.py index 7656b279004..324450bf80e 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -2113,7 +2113,18 @@ class Image(Binary): super(Image, self).create(new_record_values) def write(self, records, value): - new_value = self._image_process(value) + try: + new_value = self._image_process(value) + except UserError: + if not any(records._ids): + # Some crap is assigned to a new record. This can happen in an + # onchange, where the client sends the "bin size" value of the + # field instead of its full value (this saves bandwidth). In + # this case, we simply don't assign the field: its value will be + # taken from the records' origin. + return + raise + super(Image, self).write(records, new_value) cache_value = self.convert_to_cache(value if self.related else new_value, records) records.env.cache.update(records, self, [cache_value] * len(records))