From ed86228e86785f2d3128232d7412fef0e30533ce Mon Sep 17 00:00:00 2001 From: Andrey Mozgunov Date: Tue, 26 Sep 2017 15:51:34 +0300 Subject: [PATCH 1/2] Fix inline body parsing --- imbox/parser.py | 2 +- tests/parser_tests.py | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/imbox/parser.py b/imbox/parser.py index 9d83fe3..253ef82 100644 --- a/imbox/parser.py +++ b/imbox/parser.py @@ -149,7 +149,7 @@ def parse_email(raw_email, policy=None): for part in email_message.walk(): content_type = part.get_content_type() part_maintype = part.get_content_maintype() - content_disposition = part.get('Content-Disposition', None) + content_disposition = part.get_content_disposition() if content_disposition or not part_maintype == "text": content = part.get_payload(decode=True) else: diff --git a/tests/parser_tests.py b/tests/parser_tests.py index 7d1fba7..95df74f 100644 --- a/tests/parser_tests.py +++ b/tests/parser_tests.py @@ -82,6 +82,62 @@ Content-Transfer-Encoding: quoted-printable """ +raw_email_encoded_another_bad_multipart = b"""Delivered-To: receiver@example.com +Return-Path: +Mime-Version: 1.0 +Date: Wed, 22 Mar 2017 15:21:55 -0500 +Message-ID: <58D29693.192A.0075.1@wimort.com> +Subject: Re: Reaching Out About Peoples Home Equity +From: sender@example.com +To: receiver@example.com +Content-Type: multipart/alternative; boundary="____NOIBTUQXSYRVOOAFLCHY____" + + +--____NOIBTUQXSYRVOOAFLCHY____ +Content-Type: text/plain; charset=iso-8859-15 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline; + modification-date="Wed, 22 Mar 2017 15:21:55 -0500" + +Chloe, + +--____NOIBTUQXSYRVOOAFLCHY____ +Content-Type: multipart/related; boundary="____XTSWHCFJMONXSVGPVDLY____" + + +--____XTSWHCFJMONXSVGPVDLY____ +Content-Type: text/html; charset=iso-8859-15 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline; + modification-date="Wed, 22 Mar 2017 15:21:55 -0500" + + + +
Chloe,
+ +--____XTSWHCFJMONXSVGPVDLY____ +Content-ID: +Content-Type: image/gif +Content-Transfer-Encoding: base64 + +R0lGODlhHgHCAPf/AIOPr9GvT7SFcZZjVTEuMLS1tZKUlJN0Znp4eEA7PV1aWvz8+8V6Zl1BNYxX +HvOZ1/zmOd95agUEADs= +--____XTSWHCFJMONXSVGPVDLY____ +Content-ID: +Content-Type: image/xxx +Content-Transfer-Encoding: base64 + +R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw== +--____XTSWHCFJMONXSVGPVDLY____-- + +--____NOIBTUQXSYRVOOAFLCHY____-- +""" + + class TestParser(unittest.TestCase): def test_parse_email(self): @@ -98,6 +154,12 @@ class TestParser(unittest.TestCase): self.assertEqual('Выписка по карте', parsed_email.subject) self.assertEqual('Выписка по карте 1234', parsed_email.body['html'][0]) + def test_parse_email_inline_body(self): + parsed_email = parse_email(raw_email_encoded_another_bad_multipart) + self.assertEqual("Re: Reaching Out About Peoples Home Equity", parsed_email.subject) + self.assertTrue(parsed_email.body['plain']) + self.assertTrue(parsed_email.body['html']) + def test_parse_email_ignores_header_casing(self): self.assertEqual('one', parse_email('Message-ID: one').message_id) self.assertEqual('one', parse_email('Message-Id: one').message_id) From 4559149dc02733eaefdba063969d02459f0e81d3 Mon Sep 17 00:00:00 2001 From: Andrey Mozgunov Date: Wed, 27 Sep 2017 13:42:43 +0300 Subject: [PATCH 2/2] Fix content disposition reading for python < 3.5 --- imbox/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imbox/parser.py b/imbox/parser.py index 9f741b1..538ba5c 100644 --- a/imbox/parser.py +++ b/imbox/parser.py @@ -147,14 +147,14 @@ def parse_email(raw_email, policy=None): for part in email_message.walk(): content_type = part.get_content_type() part_maintype = part.get_content_maintype() - content_disposition = part.get_content_disposition() + content_disposition = part.get('Content-Disposition', None) if content_disposition or not part_maintype == "text": content = part.get_payload(decode=True) else: content = decode_content(part) is_inline = content_disposition is None \ - or content_disposition == "inline" + or content_disposition.startswith("inline") if content_type == "text/plain" and is_inline: body['plain'].append(content) elif content_type == "text/html" and is_inline: