From 0b27a371565fc229f2e82b2d7701e00229fe5051 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Wed, 10 Feb 2016 14:46:59 +0100 Subject: [PATCH] [FIX] ir_translation: validate translation values and do not sanitize them The value validation was de facto nullified by escaping invalid translations in `XMLTranslator.process_text`. Reimplement it by checking whether the translated term can be translated back to its source term in the field value. The sanitization of translated terms is now gone, as not all terms should be sanitized (like attribute values). --- openerp/addons/base/ir/ir_translation.py | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 6ebd2721bd9..f1cf5982ec2 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -532,13 +532,24 @@ class ir_translation(osv.osv): records.check_field_access_rights(fmode, model_fields[mname]) records.check_access_rule(fmode) + @api.constrains('type', 'name', 'value') + def _check_value(self): + for trans in self.with_context(lang=None): + if trans.type == 'model' and trans.value: + mname, fname = trans.name.split(',') + record = trans.env[mname].browse(trans.res_id) + field = record._fields[fname] + if callable(field.translate): + # check whether applying (trans.src -> trans.value) then + # (trans.value -> trans.src) gives the original value back + value0 = field.translate(lambda term: None, record[fname]) + value1 = field.translate({trans.src: trans.value}.get, value0) + value2 = field.translate({trans.value: trans.src}.get, value1) + if value2 != value0: + raise ValueError(_("Translation is not valid:\n%s") % trans.value) + @api.model def create(self, vals): - if vals.get('type') == 'model' and vals.get('value'): - # check and sanitize value - mname, fname = vals['name'].split(',') - field = self.env[mname]._fields[fname] - vals['value'] = field.check_trans_value(vals['value']) record = super(ir_translation, self.sudo()).create(vals).with_env(self.env) record.check('create') self.clear_caches() @@ -548,13 +559,6 @@ class ir_translation(osv.osv): def write(self, vals): if vals.get('value'): vals.setdefault('state', 'translated') - ttype = vals.get('type') or self[:1].type - if ttype == 'model': - # check and sanitize value - name = vals.get('name') or self[:1].name - mname, fname = name.split(',') - field = self.env[mname]._fields[fname] - vals['value'] = field.check_trans_value(vals['value']) elif vals.get('src') or not vals.get('value', True): vals.setdefault('state', 'to_translate') self.check('write')