]> granicus.if.org Git - python/commitdiff
[3.8] bpo-33972: Fix EmailMessage.iter_attachments raising AttributeError (GH-14119...
authorAbhilash Raj <maxking@users.noreply.github.com>
Tue, 25 Jun 2019 18:38:48 +0000 (11:38 -0700)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 25 Jun 2019 18:38:48 +0000 (11:38 -0700)
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 <maxking@users.noreply.github.com>
https://bugs.python.org/issue33972

Lib/email/message.py
Lib/test/test_email/test_message.py
Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst [new file with mode: 0644]

index b6512f2198af43fcdde27d5559fad50d3853d81c..12626026179608e198e079d69d56dbd94c594004 100644 (file)
@@ -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
index 5dc46e1b812c5d8cf2767881805416bf5613ff51..fab97d91882b8b42c962ceb3588f1df89df5f7d6 100644 (file)
@@ -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 (file)
index 0000000..ded1570
--- /dev/null
@@ -0,0 +1,2 @@
+Email with single part but content-type set to ``multipart/*`` doesn't raise
+AttributeError anymore.