mirror of
https://github.com/django/django.git
synced 2025-07-01 00:09:13 +00:00
Fixed #36478 -- Fixed inconsistent mail attachment handling.
Fixed an inconsistency between EmailMessage.attach() and .attachments when attaching bytes content with a text/* mimetype. The attach() function decodes UTF-8 bytes if possible and otherwise changes the mimetype to application/octet-stream to preserve the content's unknown encoding (refs #27007). Providing equivalent content directly in EmailMessage.attachments did not apply the same logic, leading to an "AttributeError: 'bytes' object has no attribute 'encode'" in SafeMIMEText.set_payload(). Updated EmailMessage._create_mime_attachment() to match attach()'s handling for text/* mimetypes with bytes content. Updated test cases to accurately cover behavior on both paths.
This commit is contained in:
parent
68a45d9a80
commit
23529b6627
@ -387,6 +387,15 @@ class EmailMessage:
|
|||||||
email.Message or EmailMessage object, as well as a str.
|
email.Message or EmailMessage object, as well as a str.
|
||||||
"""
|
"""
|
||||||
basetype, subtype = mimetype.split("/", 1)
|
basetype, subtype = mimetype.split("/", 1)
|
||||||
|
if basetype == "text" and isinstance(content, bytes):
|
||||||
|
# This duplicates logic from EmailMessage.attach() to properly
|
||||||
|
# handle EmailMessage.attachments not created through attach().
|
||||||
|
try:
|
||||||
|
content = content.decode()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
|
||||||
|
basetype, subtype = mimetype.split("/", 1)
|
||||||
|
|
||||||
if basetype == "text":
|
if basetype == "text":
|
||||||
encoding = self.encoding or settings.DEFAULT_CHARSET
|
encoding = self.encoding or settings.DEFAULT_CHARSET
|
||||||
attachment = SafeMIMEText(content, subtype, encoding)
|
attachment = SafeMIMEText(content, subtype, encoding)
|
||||||
|
@ -901,12 +901,39 @@ class MailTests(MailTestsMixin, SimpleTestCase):
|
|||||||
self.assertEqual(actual.mimetype, expected_mimetype)
|
self.assertEqual(actual.mimetype, expected_mimetype)
|
||||||
|
|
||||||
def test_attach_text_as_bytes(self):
|
def test_attach_text_as_bytes(self):
|
||||||
msg = EmailMessage()
|
"""
|
||||||
msg.attach("file.txt", b"file content\n")
|
For text/* attachments, EmailMessage.attach() decodes bytes as UTF-8
|
||||||
filename, content, mimetype = self.get_decoded_attachments(msg)[0]
|
if possible and changes to DEFAULT_ATTACHMENT_MIME_TYPE if not.
|
||||||
self.assertEqual(filename, "file.txt")
|
"""
|
||||||
self.assertEqual(content, "file content\n")
|
email = EmailMessage()
|
||||||
self.assertEqual(mimetype, "text/plain")
|
# Mimetype guessing identifies these as text/plain from the .txt extensions.
|
||||||
|
email.attach("utf8.txt", "ütƒ-8\n".encode())
|
||||||
|
email.attach("not-utf8.txt", b"\x86unknown-encoding\n")
|
||||||
|
attachments = self.get_decoded_attachments(email)
|
||||||
|
self.assertEqual(attachments[0], ("utf8.txt", "ütƒ-8\n", "text/plain"))
|
||||||
|
self.assertEqual(
|
||||||
|
attachments[1],
|
||||||
|
("not-utf8.txt", b"\x86unknown-encoding\n", "application/octet-stream"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_attach_text_as_bytes_using_property(self):
|
||||||
|
"""
|
||||||
|
The logic described in test_attach_text_as_bytes() also applies
|
||||||
|
when directly setting the EmailMessage.attachments property.
|
||||||
|
"""
|
||||||
|
email = EmailMessage()
|
||||||
|
email.attachments = [
|
||||||
|
("utf8.txt", "ütƒ-8\n".encode(), "text/plain"),
|
||||||
|
("not-utf8.txt", b"\x86unknown-encoding\n", "text/plain"),
|
||||||
|
]
|
||||||
|
attachments = self.get_decoded_attachments(email)
|
||||||
|
self.assertEqual(len(attachments), 2)
|
||||||
|
attachments = self.get_decoded_attachments(email)
|
||||||
|
self.assertEqual(attachments[0], ("utf8.txt", "ütƒ-8\n", "text/plain"))
|
||||||
|
self.assertEqual(
|
||||||
|
attachments[1],
|
||||||
|
("not-utf8.txt", b"\x86unknown-encoding\n", "application/octet-stream"),
|
||||||
|
)
|
||||||
|
|
||||||
def test_attach_utf8_text_as_bytes(self):
|
def test_attach_utf8_text_as_bytes(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user