diff --git a/openerp/tests/test_mail.py b/openerp/tests/test_mail.py
index a8c806a13d0..b3c11a13bfe 100644
--- a/openerp/tests/test_mail.py
+++ b/openerp/tests/test_mail.py
@@ -177,6 +177,10 @@ class TestCleaner(unittest2.TestCase):
new_html = html_email_clean(False)
self.assertEqual(new_html, False, 'html_email_cleaner did change a False in an other value.')
+ # Test6: Message with xml and doctype tags don't crash
+ new_html = html_email_clean(u'\n\n\n
\n 404 - Not Found\n \n \n 404 - Not Found
\n \n\n')
+ self.assertNotIn('encoding', new_html, 'html_email_cleaner did not remove correctly encoding attributes')
+
class TestHtmlTools(unittest2.TestCase):
""" Test some of our generic utility functions about html """
diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py
index a54f99ba1ad..e6b471a26ba 100644
--- a/openerp/tools/mail.py
+++ b/openerp/tools/mail.py
@@ -130,11 +130,15 @@ def html_email_clean(html):
dest += source[idx:]
return dest
- if not html:
+ if not html or not isinstance(html, basestring):
return html
html = ustr(html)
+ # 0. remove encoding attribute inside tags
+ doctype = re.compile(r'(<[^>]*\s)(encoding=(["\'][^"\']*?["\']|[^\s\n\r>]+)(\s[^>]*|/)?>)', re.IGNORECASE | re.DOTALL)
+ html = doctype.sub(r"", html)
+
# 1.
-> \n, because otherwise the tree is obfuscated
br_tags = re.compile(r'([<]\s*[bB][rR]\s*\/?[>])')
html = _replace_matching_regex(br_tags, html, '__BR_TAG__')