]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42892: fix email multipart attribute error (GH-26903) (GH-27492)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 30 Jul 2021 17:27:06 +0000 (10:27 -0700)
committerGitHub <noreply@github.com>
Fri, 30 Jul 2021 17:27:06 +0000 (19:27 +0200)
(cherry picked from commit e3f877c32d7cccb734f45310f26beeec793364ce)

Co-authored-by: andrei kulakov <andrei.avk@gmail.com>
Lib/email/message.py
Lib/test/test_email/test_message.py
Misc/NEWS.d/next/Library/2021-06-24-19-16-20.bpo-42892.qvRNhI.rst [new file with mode: 0644]

index db30d9a17089928010629c722769d681a2b6515a..6752ce0fa138255f7e31320d2840abe5c903278a 100644 (file)
@@ -982,7 +982,7 @@ class MIMEPart(Message):
             if subtype in preferencelist:
                 yield (preferencelist.index(subtype), part)
             return
-        if maintype != 'multipart':
+        if maintype != 'multipart' or not self.is_multipart():
             return
         if subtype != 'related':
             for subpart in part.iter_parts():
@@ -1087,7 +1087,7 @@ class MIMEPart(Message):
 
         Return an empty iterator for a non-multipart.
         """
-        if self.get_content_maintype() == 'multipart':
+        if self.is_multipart():
             yield from self.get_payload()
 
     def get_content(self, *args, content_manager=None, **kw):
index 7aaf780c042b03c9afdbf5ff7f7e39d34630b669..920a3d6a9cb91be87612fe39f615ae60e840c99a 100644 (file)
@@ -487,10 +487,14 @@ class TestEmailMessageBase:
         self.assertEqual(list(m.iter_attachments()), attachments)
 
     def message_as_iter_parts(self, body_parts, attachments, parts, msg):
+        def _is_multipart_msg(msg):
+            return 'Content-Type: multipart' in msg
+
         m = self._str_msg(msg)
         allparts = list(m.walk())
         parts = [allparts[n] for n in parts]
-        self.assertEqual(list(m.iter_parts()), parts)
+        iter_parts = list(m.iter_parts()) if _is_multipart_msg(msg) else []
+        self.assertEqual(iter_parts, parts)
 
     class _TestContentManager:
         def get_content(self, msg, *args, **kw):
@@ -923,6 +927,34 @@ class TestEmailMessage(TestEmailMessageBase, TestEmailBase):
                          b'123456789-123456789\n 123456789 Hello '
                          b'=?utf-8?q?W=C3=B6rld!?= 123456789 123456789\n\n')
 
+    def test_get_body_malformed(self):
+        """test for bpo-42892"""
+        msg = textwrap.dedent("""\
+            Message-ID: <674392CA.4347091@email.au>
+            Date: Wed, 08 Nov 2017 08:50:22 +0700
+            From: Foo Bar <email@email.au>
+            MIME-Version: 1.0
+            To: email@email.com <email@email.com>
+            Subject: Python Email
+            Content-Type: multipart/mixed;
+            boundary="------------879045806563892972123996"
+            X-Global-filter:Messagescannedforspamandviruses:passedalltests
+
+            This is a multi-part message in MIME format.
+            --------------879045806563892972123996
+            Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+            Content-Transfer-Encoding: 7bit
+
+            Your message is ready to be sent with the following file or link
+            attachments:
+            XU89 - 08.11.2017
+            """)
+        m = self._str_msg(msg)
+        # In bpo-42892, this would raise
+        # AttributeError: 'str' object has no attribute 'is_attachment'
+        m.get_body()
+
+
 class TestMIMEPart(TestEmailMessageBase, TestEmailBase):
     # Doing the full test run here may seem a bit redundant, since the two
     # classes are almost identical.  But what if they drift apart?  So we do
diff --git a/Misc/NEWS.d/next/Library/2021-06-24-19-16-20.bpo-42892.qvRNhI.rst b/Misc/NEWS.d/next/Library/2021-06-24-19-16-20.bpo-42892.qvRNhI.rst
new file mode 100644 (file)
index 0000000..3c70b05
--- /dev/null
@@ -0,0 +1 @@
+Fixed an exception thrown while parsing a malformed multipart email by :class:`email.message.EmailMessage`.