From 3a0be47f7e98633b9a83e3db41e413112e261736 Mon Sep 17 00:00:00 2001 From: martinezleoml Date: Thu, 20 Jul 2023 18:07:17 +0200 Subject: [PATCH] fix: handle attachments from Apple Mail client --- anymail/inbound.py | 4 +++- tests/test_inbound.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/anymail/inbound.py b/anymail/inbound.py index 97d7d540..8fa19b32 100644 --- a/anymail/inbound.py +++ b/anymail/inbound.py @@ -145,7 +145,9 @@ def _get_body_content(self, content_type): # Hoisted from email.message.MIMEPart def is_attachment(self): - return self.get_content_disposition() == "attachment" + return self.get_content_disposition() == "attachment" or ( + self.get_content_disposition() == "inline" and self["Content-ID"] is None + ) # New for Anymail def is_inline_attachment(self): diff --git a/tests/test_inbound.py b/tests/test_inbound.py index 0f0d75bf..08fb80a6 100644 --- a/tests/test_inbound.py +++ b/tests/test_inbound.py @@ -540,6 +540,33 @@ def test_attachment_as_uploaded_file_security(self): self.assertEqual(attachments[1].get_filename(), "../static/index.html") self.assertEqual(attachments[1].as_uploaded_file().name, "index.html") + def test_attachment_issued_by_apple_mail(self): + # Attachments issued by Apple Mail client are sometimes included as inline + # attachments without Content-ID. They should then be considered as regular + # attachments. + raw = dedent( + """\ + MIME-Version: 1.0 + Subject: Attachment test + Content-Type: multipart/mixed; boundary="this_is_a_boundary" + + --this_is_a_boundary + Content-Disposition: inline; filename=pixel.png + Content-Type: image/png; x-unix-mode=0644; name="pixel.png" + Content-Transfer-Encoding: base64 + + iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA + AXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAQSURBVHgBAQUA+v8AAAAA/wEEAQB5fl4xAAAA + AElFTkSuQmCC + --this_is_a_boundary + """ + ) + msg = AnymailInboundMessage.parse_raw_mime(raw) + attachments = msg.attachments + + self.assertEqual(attachments[0].get_filename(), "pixel.png") + self.assertEqual(attachments[0].get_content_type(), "image/png") + class AnymailInboundMessageAttachedMessageTests(SimpleTestCase): # message/rfc822 attachments should get parsed recursively