Skip to content

Commit

Permalink
bpo-42892: fix email multipart attribute error (GH-26903)
Browse files Browse the repository at this point in the history
  • Loading branch information
akulakov authored Jul 30, 2021
1 parent 4bd9caa commit e3f877c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Lib/email/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ def _find_body(self, part, preferencelist):
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():
Expand Down Expand Up @@ -1087,7 +1087,7 @@ def iter_parts(self):
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):
Expand Down
34 changes: 33 additions & 1 deletion Lib/test/test_email/test_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,14 @@ def message_as_iter_attachment(self, body_parts, attachments, parts, msg):
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):
Expand Down Expand Up @@ -923,6 +927,34 @@ def test_folding_with_utf8_encoding_8(self):
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed an exception thrown while parsing a malformed multipart email by :class:`email.message.EmailMessage`.

0 comments on commit e3f877c

Please sign in to comment.