diff --git a/openerp/addons/base/tests/test_mail.py b/openerp/addons/base/tests/test_mail.py index 4ebec837c6d272d1a11faee03161d5ad4d81738a..01193de9962e0a32a5a1f4ca01b4a72d48b99a13 100644 --- a/openerp/addons/base/tests/test_mail.py +++ b/openerp/addons/base/tests/test_mail.py @@ -24,10 +24,7 @@ import unittest2 -from lxml import etree - from openerp.tools import html_sanitize, html_email_clean, append_content_to_html, plaintext2html, email_split - import test_mail_examples @@ -45,6 +42,24 @@ class TestSanitizer(unittest2.TestCase): html = html_sanitize(content) self.assertEqual(html, expected, 'html_sanitize is broken') + def test_mako(self): + cases = [ + ('''<p>Some text</p> +<% set signup_url = object.get_signup_url() %> +% if signup_url: +<p> + You can access this document and pay online via our Customer Portal: +</p>''', '''<p>Some text</p> +<% set signup_url = object.get_signup_url() %> +% if signup_url: +<p> + You can access this document and pay online via our Customer Portal: +</p>''') + ] + for content, expected in cases: + html = html_sanitize(content, silent=False) + self.assertEqual(html, expected, 'html_sanitize: broken mako management') + def test_evil_malicious_code(self): # taken from https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Tests cases = [ @@ -363,16 +378,17 @@ class TestHtmlTools(unittest2.TestCase): for html, content, plaintext_flag, preserve_flag, container_tag, expected in test_samples: self.assertEqual(append_content_to_html(html, content, plaintext_flag, preserve_flag, container_tag), expected, 'append_content_to_html is broken') + class TestEmailTools(unittest2.TestCase): """ Test some of our generic utility functions for emails """ def test_email_split(self): cases = [ - ("John <12345@gmail.com>", ['12345@gmail.com']), # regular form - ("d@x; 1@2", ['d@x', '1@2']), # semi-colon + extra space - ("'(ss)' <123@gmail.com>, 'foo' <foo@bar>", ['123@gmail.com','foo@bar']), # comma + single-quoting - ('"john@gmail.com"<johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting - ('"<jg>" <johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting with brackets + ("John <12345@gmail.com>", ['12345@gmail.com']), # regular form + ("d@x; 1@2", ['d@x', '1@2']), # semi-colon + extra space + ("'(ss)' <123@gmail.com>, 'foo' <foo@bar>", ['123@gmail.com', 'foo@bar']), # comma + single-quoting + ('"john@gmail.com"<johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting + ('"<jg>" <johnny@gmail.com>', ['johnny@gmail.com']), # double-quoting with brackets ] for text, expected in cases: self.assertEqual(email_split(text), expected, 'email_split is broken') diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py index 83bd951174b1e98a68ed3e9db8e070baebefeb79..f6406ebb67a190820391a533fbd9bbebbc2a8423 100644 --- a/openerp/tools/mail.py +++ b/openerp/tools/mail.py @@ -63,6 +63,9 @@ def html_sanitize(src, silent=True, strict=False): # html encode email tags part = re.compile(r"(<(([^a<>]|a[^<>\s])[^<>]*)@[^<>]+>)", re.IGNORECASE | re.DOTALL) src = part.sub(lambda m: cgi.escape(m.group(1)), src) + # html encode mako tags <% ... %> to decode them later and keep them alive, otherwise they are stripped by the cleaner + src = src.replace('<%', cgi.escape('<%')) + src = src.replace('%>', cgi.escape('%>')) kwargs = { 'page_structure': True, @@ -71,7 +74,7 @@ def html_sanitize(src, silent=True, strict=False): 'remove_unknown_tags': False, 'allow_tags': allowed_tags, 'comments': False, - 'processing_instructions' : False + 'processing_instructions': False } if etree.LXML_VERSION >= (2, 3, 1): # kill_tags attribute has been added in version 2.3.1 @@ -104,6 +107,8 @@ def html_sanitize(src, silent=True, strict=False): cleaned = cleaned.replace('%20', ' ') cleaned = cleaned.replace('%5B', '[') cleaned = cleaned.replace('%5D', ']') + cleaned = cleaned.replace('<%', '<%') + cleaned = cleaned.replace('%>', '%>') except etree.ParserError, e: if 'empty' in str(e): return ""