From ccc088f8ced67a9ea57a6ee1e00964f2cf6baffd Mon Sep 17 00:00:00 2001 From: Florian Apolloner Date: Wed, 15 Jul 2020 07:30:15 +0200 Subject: [3.0.x] Fixed #31784 -- Fixed crash when sending emails on Python 3.6.11+, 3.7.8+, and 3.8.4+. Fixed sending emails crash on email addresses with display names longer then 75 chars on Python 3.6.11+, 3.7.8+, and 3.8.4+. Wrapped display names were passed to email.headerregistry.Address() what caused raising an exception because address parts cannot contain CR or LF. See https://bugs.python.org/issue39073 Co-Authored-By: Mariusz Felisiak Backport of 96a3ea39ef0790dbc413dde0a3e19f6a769356a2 from master --- django/core/mail/message.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'django') diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 607eb4af0b..963542cd62 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -10,7 +10,7 @@ from email.mime.base import MIMEBase from email.mime.message import MIMEMessage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.utils import formatdate, getaddresses, make_msgid +from email.utils import formataddr, formatdate, getaddresses, make_msgid from io import BytesIO, StringIO from pathlib import Path @@ -96,16 +96,24 @@ def sanitize_address(addr, encoding): nm, address = addr localpart, domain = address.rsplit('@', 1) - nm = Header(nm, encoding).encode() + address_parts = nm + localpart + domain + if '\n' in address_parts or '\r' in address_parts: + raise ValueError('Invalid address; address parts cannot contain newlines.') + # Avoid UTF-8 encode, if it's possible. + try: + nm.encode('ascii') + nm = Header(nm).encode() + except UnicodeEncodeError: + nm = Header(nm, encoding).encode() try: localpart.encode('ascii') except UnicodeEncodeError: localpart = Header(localpart, encoding).encode() domain = punycode(domain) - parsed_address = Address(nm, username=localpart, domain=domain) - return str(parsed_address) + parsed_address = Address(username=localpart, domain=domain) + return formataddr((nm, parsed_address.addr_spec)) class MIMEMixin: -- cgit v1.3