From: Abhilash Raj Date: Tue, 25 Jun 2019 18:38:48 +0000 (-0700) Subject: [3.8] bpo-33972: Fix EmailMessage.iter_attachments raising AttributeError (GH-14119... X-Git-Tag: v3.8.0b2~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6e32824cf038386174fe2b9e7273e4779c9958c;p=python [3.8] bpo-33972: Fix EmailMessage.iter_attachments raising AttributeError (GH-14119) (GH-14380) When certain malformed messages have content-type set to 'mulitpart/*' but still have a single part body, iter_attachments can raise AttributeError. This patch fixes it by returning a None value instead when the body is single part. (cherry picked from commit 02257012f6d3821d816cb6a7e8461a88a05b9a08) Co-authored-by: Abhilash Raj https://bugs.python.org/issue33972 --- diff --git a/Lib/email/message.py b/Lib/email/message.py index b6512f2198..1262602617 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -1041,7 +1041,16 @@ class MIMEPart(Message): maintype, subtype = self.get_content_type().split('/') if maintype != 'multipart' or subtype == 'alternative': return - parts = self.get_payload().copy() + payload = self.get_payload() + # Certain malformed messages can have content type set to `multipart/*` + # but still have single part body, in which case payload.copy() can + # fail with AttributeError. + try: + parts = payload.copy() + except AttributeError: + # payload is not a list, it is most probably a string. + return + if maintype == 'multipart' and subtype == 'related': # For related, we treat everything but the root as an attachment. # The root may be indicated by 'start'; if there's no start or we diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index 5dc46e1b81..fab97d9188 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -929,6 +929,15 @@ class TestMIMEPart(TestEmailMessageBase, TestEmailBase): m.set_content(content_manager=cm) self.assertNotIn('MIME-Version', m) + def test_string_payload_with_multipart_content_type(self): + msg = message_from_string(textwrap.dedent("""\ + Content-Type: multipart/mixed; charset="utf-8" + + sample text + """), policy=policy.default) + attachments = msg.iter_attachments() + self.assertEqual(list(attachments), []) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst b/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst new file mode 100644 index 0000000000..ded1570b30 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst @@ -0,0 +1,2 @@ +Email with single part but content-type set to ``multipart/*`` doesn't raise +AttributeError anymore.