diff options
| author | Sergei Maertens <sergei@maykinmedia.nl> | 2016-04-02 11:41:47 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-05-06 14:34:11 -0400 |
| commit | ec009ef1d8470f8fdb32802339fe2615e35887a1 (patch) | |
| tree | a70aaeef022d73533398ac288c85f047b3ebd513 /tests | |
| parent | 086510fde00d8246be3c7cdbd268742ece8cc401 (diff) | |
Fixed #25986 -- Fixed crash sending email with non-ASCII in local part of the address.
On Python 3, sending emails failed for addresses containing non-ASCII
characters due to the usage of the legacy Python email.utils.formataddr()
function. This is fixed by using the proper Address object on Python 3.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/mail/tests.py | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 4e7075e695..7988e08612 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -9,6 +9,7 @@ import smtpd import sys import tempfile import threading +from email.header import Header from email.mime.text import MIMEText from smtplib import SMTP, SMTPException from ssl import SSLError @@ -19,7 +20,7 @@ from django.core.mail import ( send_mail, send_mass_mail, ) from django.core.mail.backends import console, dummy, filebased, locmem, smtp -from django.core.mail.message import BadHeaderError +from django.core.mail.message import BadHeaderError, sanitize_address from django.test import SimpleTestCase, override_settings from django.utils._os import upath from django.utils.encoding import force_bytes, force_text @@ -567,6 +568,42 @@ class MailTests(HeadersCheckMixin, SimpleTestCase): # Verify that the child message header is not base64 encoded self.assertIn(str('Child Subject'), parent_s) + def test_sanitize_address(self): + """ + Email addresses are properly sanitized. + """ + # Simple ASCII address - string form + self.assertEqual(sanitize_address('to@example.com', 'ascii'), 'to@example.com') + self.assertEqual(sanitize_address('to@example.com', 'utf-8'), 'to@example.com') + # Bytestrings are transformed to normal strings. + self.assertEqual(sanitize_address(b'to@example.com', 'utf-8'), 'to@example.com') + + # Simple ASCII address - tuple form + self.assertEqual( + sanitize_address(('A name', 'to@example.com'), 'ascii'), + 'A name <to@example.com>' + ) + if PY3: + self.assertEqual( + sanitize_address(('A name', 'to@example.com'), 'utf-8'), + '=?utf-8?q?A_name?= <to@example.com>' + ) + else: + self.assertEqual( + sanitize_address(('A name', 'to@example.com'), 'utf-8'), + 'A name <to@example.com>' + ) + + # Unicode characters are are supported in RFC-6532. + self.assertEqual( + sanitize_address('tó@example.com', 'utf-8'), + '=?utf-8?b?dMOz?=@example.com' + ) + self.assertEqual( + sanitize_address(('Tó Example', 'tó@example.com'), 'utf-8'), + '=?utf-8?q?T=C3=B3_Example?= <=?utf-8?b?dMOz?=@example.com>' + ) + class PythonGlobalState(SimpleTestCase): """ @@ -1026,6 +1063,15 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): data = data.encode('utf-8') m = message_from_bytes(data) maddr = parseaddr(m.get('from'))[1] + + if mailfrom != maddr: + # According to the spec, mailfrom does not necessarily match the + # From header - on Python 3 this is the case where the local part + # isn't encoded, so try to correct that. + lp, domain = mailfrom.split('@', 1) + lp = Header(lp, 'utf-8').encode() + mailfrom = '@'.join([lp, domain]) + if mailfrom != maddr: return "553 '%s' != '%s'" % (mailfrom, maddr) with self.sink_lock: |
