[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
This commit is contained in:
Raphael Collet
2020-10-13 17:28:48 +00:00
parent f0ba2dbfa5
commit 11d521d918
2 changed files with 20 additions and 2 deletions
@@ -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'
+12 -1
View File
@@ -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))