mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #23063 -- Convert \n and \r to \r\n when using the SMTP backend as per RFC.
This commit is contained in:
		| @@ -120,7 +120,7 @@ class EmailBackend(BaseEmailBackend): | ||||
|                       for addr in email_message.recipients()] | ||||
|         message = email_message.message() | ||||
|         try: | ||||
|             self.connection.sendmail(from_email, recipients, message.as_bytes()) | ||||
|             self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n')) | ||||
|         except smtplib.SMTPException: | ||||
|             if not self.fail_silently: | ||||
|                 raise | ||||
|   | ||||
| @@ -123,7 +123,7 @@ def sanitize_address(addr, encoding): | ||||
|  | ||||
|  | ||||
| class MIMEMixin(): | ||||
|     def as_string(self, unixfrom=False): | ||||
|     def as_string(self, unixfrom=False, linesep='\n'): | ||||
|         """Return the entire formatted message as a string. | ||||
|         Optional `unixfrom' when True, means include the Unix From_ envelope | ||||
|         header. | ||||
| @@ -133,13 +133,16 @@ class MIMEMixin(): | ||||
|         """ | ||||
|         fp = six.StringIO() | ||||
|         g = generator.Generator(fp, mangle_from_=False) | ||||
|         g.flatten(self, unixfrom=unixfrom) | ||||
|         if six.PY2: | ||||
|             g.flatten(self, unixfrom=unixfrom) | ||||
|         else: | ||||
|             g.flatten(self, unixfrom=unixfrom, linesep=linesep) | ||||
|         return fp.getvalue() | ||||
|  | ||||
|     if six.PY2: | ||||
|         as_bytes = as_string | ||||
|     else: | ||||
|         def as_bytes(self, unixfrom=False): | ||||
|         def as_bytes(self, unixfrom=False, linesep='\n'): | ||||
|             """Return the entire formatted message as bytes. | ||||
|             Optional `unixfrom' when True, means include the Unix From_ envelope | ||||
|             header. | ||||
| @@ -149,7 +152,7 @@ class MIMEMixin(): | ||||
|             """ | ||||
|             fp = six.BytesIO() | ||||
|             g = generator.BytesGenerator(fp, mangle_from_=False) | ||||
|             g.flatten(self, unixfrom=unixfrom) | ||||
|             g.flatten(self, unixfrom=unixfrom, linesep=linesep) | ||||
|             return fp.getvalue() | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -115,3 +115,5 @@ Bugfixes | ||||
|   (:ticket:`23609`). | ||||
|  | ||||
| * Fixed generic relations in ``ModelAdmin.list_filter`` (:ticket:`23616`). | ||||
|  | ||||
| * Restored RFC compliance for the SMTP backend on Python 3 (:ticket:`23063`). | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import smtpd | ||||
| import sys | ||||
| import tempfile | ||||
| import threading | ||||
| from smtplib import SMTPException | ||||
| from smtplib import SMTPException, SMTP | ||||
| from ssl import SSLError | ||||
|  | ||||
| from django.core import mail | ||||
| @@ -1038,3 +1038,37 @@ class SMTPBackendTests(BaseEmailBackendTests, SimpleTestCase): | ||||
|     def test_email_timeout_override_settings(self): | ||||
|         backend = smtp.EmailBackend() | ||||
|         self.assertEqual(backend.timeout, 10) | ||||
|  | ||||
|     def test_email_msg_uses_crlf(self): | ||||
|         """#23063 -- Test that RFC-compliant messages are sent over SMTP.""" | ||||
|         send = SMTP.send | ||||
|         try: | ||||
|             smtp_messages = [] | ||||
|  | ||||
|             def mock_send(self, s): | ||||
|                 smtp_messages.append(s) | ||||
|                 return send(self, s) | ||||
|  | ||||
|             SMTP.send = mock_send | ||||
|  | ||||
|             email = EmailMessage('Subject', 'Content', 'from@example.com', ['to@example.com']) | ||||
|             mail.get_connection().send_messages([email]) | ||||
|  | ||||
|             # Find the actual message | ||||
|             msg = None | ||||
|             for i, m in enumerate(smtp_messages): | ||||
|                 if m[:4] == 'data': | ||||
|                     msg = smtp_messages[i+1] | ||||
|                     break | ||||
|  | ||||
|             self.assertTrue(msg) | ||||
|  | ||||
|             if PY3: | ||||
|                 msg = msg.decode('utf-8') | ||||
|             # Ensure that the message only contains CRLF and not combinations of CRLF, LF, and CR. | ||||
|             msg = msg.replace('\r\n', '') | ||||
|             self.assertNotIn('\r', msg) | ||||
|             self.assertNotIn('\n', msg) | ||||
|  | ||||
|         finally: | ||||
|             SMTP.send = send | ||||
|   | ||||
		Reference in New Issue
	
	Block a user