diff options
| -rw-r--r-- | service/pixelated/adapter/model/mail.py | 24 | ||||
| -rw-r--r-- | service/test/unit/adapter/test_mail.py | 10 | 
2 files changed, 24 insertions, 10 deletions
| diff --git a/service/pixelated/adapter/model/mail.py b/service/pixelated/adapter/model/mail.py index 7e0d5ad1..8e7b745c 100644 --- a/service/pixelated/adapter/model/mail.py +++ b/service/pixelated/adapter/model/mail.py @@ -239,22 +239,26 @@ class PixelatedMail(Mail):          content_type = self._parse_charset_header(part['headers'].get('Content-Type'))          try: -            decoding_map = { -                'quoted-printable': lambda content, content_type: content.decode('quopri').decode(content_type), -                'base64': lambda content, content_type: content.decode('base64').decode('utf-8'), -                '7bit': lambda content, content_type: content.encode(content_type), -                '8bit': lambda content, content_type: content.encode(content_type) -            } -            if encoding: -                return self._decode_content_with_fallback(part['content'], decoding_map[encoding], content_type) -            else: -                return self._decode_content_with_fallback(part['content'], lambda content, content_type: content.encode(content_type), 'ascii') +            decoding_func = self._decoding_function_for_encoding(encoding) +            return self._decode_content_with_fallback(part['content'], decoding_func, content_type)          except Exception:              logger.error('Failed to decode mail part with:')              logger.error('Content-Transfer-Encoding: %s' % encoding)              logger.error('Content-Type: %s' % part['headers'].get('Content-Type'))              raise +    def _decoding_function_for_encoding(self, encoding): +        decoding_map = { +            'quoted-printable': lambda content, content_type: content.decode('quopri').decode(content_type), +            'base64': lambda content, content_type: content.decode('base64').decode('utf-8'), +            '7bit': lambda content, content_type: content.encode(content_type), +            '8bit': lambda content, content_type: content.encode(content_type) +        } +        if encoding in decoding_map: +            return decoding_map[encoding] +        else: +            return decoding_map['8bit'] +      def _decode_content_with_fallback(self, content, decode_func, content_type):          try:              return decode_func(content, content_type) diff --git a/service/test/unit/adapter/test_mail.py b/service/test/unit/adapter/test_mail.py index dbad72b3..1a9280ff 100644 --- a/service/test/unit/adapter/test_mail.py +++ b/service/test/unit/adapter/test_mail.py @@ -241,6 +241,16 @@ class TestPixelatedMail(unittest.TestCase):          self.assertEquals(u'H=E4llo', mail.text_plain_body) +    def test_broken_encoding_defaults_to_8bit(self): +        plain_headers = {'Content-Type': 'text/plain;\ncharset=iso-8859-1', 'Content-Transfer-Encoding': 'I lie to you!'} +        html_headers = {'Content-Type': 'text/html;\ncharset=utf-8', 'Content-Transfer-Encoding': 'quoted-printable'} +        parts = {'alternatives': [{'content': 'H=E4llo', 'headers': plain_headers}, {'content': '<p>H=C3=A4llo</p>', 'headers': html_headers}]} + +        mail = PixelatedMail.from_soledad(None, None, self._create_bdoc(raw='some raw body'), parts=parts, soledad_querier=None) + +        self.assertEquals(u'H=E4llo', mail.text_plain_body) +        self.assertEquals(u'<p>H\xe4llo</p>', mail.html_body) +      def test_clean_line_breaks_on_address_headers(self):          many_recipients = 'One <one@mail.com>,\nTwo <two@mail.com>, Normal <normal@mail.com>,\nalone@mail.com'          headers = {'Cc': many_recipients, | 
