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 --- tests/mail/tests.py | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 6de819965a..accdba5e4a 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -722,14 +722,14 @@ class MailTests(HeadersCheckMixin, SimpleTestCase): ( ('A name', 'to@example.com'), 'utf-8', - '=?utf-8?q?A_name?= ', + 'A name ', ), ('localpartonly', 'ascii', 'localpartonly'), # ASCII addresses with display names. ('A name ', 'ascii', 'A name '), - ('A name ', 'utf-8', '=?utf-8?q?A_name?= '), + ('A name ', 'utf-8', 'A name '), ('"A name" ', 'ascii', 'A name '), - ('"A name" ', 'utf-8', '=?utf-8?q?A_name?= '), + ('"A name" ', 'utf-8', 'A name '), # Unicode addresses (supported per RFC-6532). ('tó@example.com', 'utf-8', '=?utf-8?b?dMOz?=@example.com'), ('to@éxample.com', 'utf-8', 'to@xn--xample-9ua.com'), @@ -748,20 +748,45 @@ class MailTests(HeadersCheckMixin, SimpleTestCase): ( 'To Example ', 'utf-8', - '=?utf-8?q?To_Example?= ', + 'To Example ', ), # Addresses with two @ signs. ('"to@other.com"@example.com', 'utf-8', r'"to@other.com"@example.com'), ( '"to@other.com" ', 'utf-8', - '=?utf-8?q?to=40other=2Ecom?= ', + '"to@other.com" ', ), ( ('To Example', 'to@other.com@example.com'), 'utf-8', - '=?utf-8?q?To_Example?= <"to@other.com"@example.com>', + 'To Example <"to@other.com"@example.com>', + ), + # Addresses with long unicode display names. + ( + 'Tó Example very long' * 4 + ' ', + 'utf-8', + '=?utf-8?q?T=C3=B3_Example_very_longT=C3=B3_Example_very_longT' + '=C3=B3_Example_?=\n' + ' =?utf-8?q?very_longT=C3=B3_Example_very_long?= ' + '', + ), + ( + ('Tó Example very long' * 4, 'to@example.com'), + 'utf-8', + '=?utf-8?q?T=C3=B3_Example_very_longT=C3=B3_Example_very_longT' + '=C3=B3_Example_?=\n' + ' =?utf-8?q?very_longT=C3=B3_Example_very_long?= ' + '', ), + # Address with long display name and unicode domain. + ( + ('To Example very long' * 4, 'to@exampl€.com'), + 'utf-8', + 'To Example very longTo Example very longTo Example very longT' + 'o Example very\n' + ' long ' + ) ): with self.subTest(email_address=email_address, encoding=encoding): self.assertEqual(sanitize_address(email_address, encoding), expected_result) @@ -781,6 +806,19 @@ class MailTests(HeadersCheckMixin, SimpleTestCase): with self.assertRaises(ValueError): sanitize_address(email_address, encoding='utf-8') + def test_sanitize_address_header_injection(self): + msg = 'Invalid address; address parts cannot contain newlines.' + tests = [ + 'Name\nInjection ', + ('Name\nInjection', 'to@xample.com'), + 'Name ', + ('Name', 'to\ninjection@example.com'), + ] + for email_address in tests: + with self.subTest(email_address=email_address): + with self.assertRaisesMessage(ValueError, msg): + sanitize_address(email_address, encoding='utf-8') + @requires_tz_support class MailTimeZoneTests(SimpleTestCase): -- cgit v1.3