From 42e2676f4b44a0403fd5f661d9502a9b83c0e33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 27 Feb 2014 13:02:54 +0100 Subject: [PATCH] [IMP] fields: html: now supports a sanitize argument, telling whether the content of the html field should be sanitized before storage. This parameter is true by default. Example of use: html of email template is considered as html content, but contains mako strings that makes this content not valid html. Sanitizing the body content can cause issues to the template; therefore storing it as html but not sanitized allows to keep its content safe. Added a test case to ensure this behavior. bzr revid: tde@openerp.com-20140227120254-6m8gvkt4hf28nl0e --- openerp/osv/fields.py | 19 ++++++++++---- openerp/tests/test_fields.py | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 478f982cd69..d5d0ee0fa30 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -236,15 +236,24 @@ class char(_column): class text(_column): _type = 'text' + class html(text): _type = 'html' _symbol_c = '%s' - def _symbol_f(x): - if x is None or x == False: + + def _symbol_set_html(self, value): + if value is None or value is False: return None - return html_sanitize(x) - - _symbol_set = (_symbol_c, _symbol_f) + if not self._sanitize: + return value + return html_sanitize(value) + + def __init__(self, string='unknown', sanitize=True, **args): + super(html, self).__init__(string=string, **args) + self._sanitize = sanitize + # symbol_set redefinition because of sanitize specific behavior + self._symbol_f = self._symbol_set_html + self._symbol_set = (self._symbol_c, self._symbol_f) import __builtin__ diff --git a/openerp/tests/test_fields.py b/openerp/tests/test_fields.py index cb05861d301..c767c9273ea 100644 --- a/openerp/tests/test_fields.py +++ b/openerp/tests/test_fields.py @@ -180,3 +180,51 @@ class TestPropertyField(common.TransactionCase): self.partner.write(cr, alice, [partner_id], {'property_country': country_be}) self.assertEqual(self.partner.browse(cr, alice, partner_id).property_country.id, country_be, "Alice does not see the value he has set on the property field") self.assertEqual(self.partner.browse(cr, bob, partner_id).property_country.id, country_fr, "Changes made by Alice have overwritten Bob's value") + + +class TestHtmlField(common.TransactionCase): + + def setUp(self): + super(TestHtmlField, self).setUp() + self.partner = self.registry('res.partner') + + def test_00_sanitize(self): + cr, uid, context = self.cr, self.uid, {} + old_columns = self.partner._columns + self.partner._columns = dict(old_columns) + self.partner._columns.update({ + 'comment': fields.html('Secure Html', sanitize=False), + }) + some_ugly_html = """

Oops this should maybe be sanitized +% if object.some_field and not object.oriented: + + % if object.other_field: + + ${object.mako_thing} + + % endif + +%if object.dummy_field: +

Youpie

+%endif""" + + pid = self.partner.create(cr, uid, { + 'name': 'Raoul Poilvache', + 'comment': some_ugly_html, + }, context=context) + partner = self.partner.browse(cr, uid, pid, context=context) + self.assertEqual(partner.comment, some_ugly_html, 'Error in HTML field: content was sanitized but field has sanitize=False') + + self.partner._columns.update({ + 'comment': fields.html('Unsecure Html', sanitize=True), + }) + self.partner.write(cr, uid, [pid], { + 'comment': some_ugly_html, + }, context=context) + partner = self.partner.browse(cr, uid, pid, context=context) + # sanitize should have closed tags left open in the original html + self.assertIn('
+
', partner.comment, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True') + self.assertIn('', partner.comment, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True') + + self.partner._columns = old_columns