From 6872aae8ef9c1a1fc6a8283aa9d12ce3a6859157 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 7 Jan 2016 11:32:03 +0100 Subject: [PATCH] [FIX] tools: do not crash on wrong translations in view During the construction a xml/html_translate content, in case of a wrongly translated part (e.g. not correctly escaped char or bad xml tag), escape the translation. The verification is done during the rendering on the view which is not the most optimal solution but has the advantage of working on system with some broken translations and does not requires to reload the translations. In master version, the verification could be done when loading the .po files. --- openerp/tools/translate.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 04022058318..dc8899e7290 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -169,9 +169,10 @@ class XMLTranslator(object): """ - def __init__(self, callback, method): + def __init__(self, callback, method, parser=None): self.callback = callback # callback function to translate terms self.method = method # serialization method ('xml' or 'html') + self.parser = parser # parser for validating translations self._done = [] # translated strings self._todo = [] # todo strings that come after _done self.needs_trans = False # whether todo needs translation @@ -208,7 +209,15 @@ class XMLTranslator(object): """ Translate text.strip(), but keep the surrounding spaces from text. """ term = text.strip() trans = term and self.callback(term) - return text.replace(term, trans) if trans else text + if trans: + try: + # parse the translation to validate it + etree.fromstring("
%s
" % encode(trans), parser=self.parser) + except etree.ParseError: + # fallback: escape the translation + trans = escape(trans) + text = text.replace(term, trans) + return text def process(self, node): """ Process the given xml `node`: collect `todo` and `done` items. """ @@ -284,9 +293,10 @@ def html_translate(callback, value): if not value: return value - trans = XMLTranslator(callback, 'html') + parser = etree.HTMLParser(encoding='utf-8') + trans = XMLTranslator(callback, 'html', parser) wrapped = "
%s
" % encode(value) - root = etree.fromstring(wrapped, etree.HTMLParser(encoding='utf-8')) + root = etree.fromstring(wrapped, parser) trans.process(root[0][0]) # html > body > div return trans.get_done()[5:-6] # remove tags
and