Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.