mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.6.x] Fixed #21093 -- Ensured that mails are not base64 encoded on python 3.3.3+.
Thanks to Arfrever for the report and Aymeric for the review.
Backport of f28ea02308 from master.
			
			
This commit is contained in:
		| @@ -5,8 +5,8 @@ import os | ||||
| import random | ||||
| import sys | ||||
| import time | ||||
| from email import generator | ||||
| from email import charset as Charset, encoders as Encoders | ||||
| from email.generator import Generator | ||||
| from email.mime.text import MIMEText | ||||
| from email.mime.multipart import MIMEMultipart | ||||
| from email.mime.base import MIMEBase | ||||
| @@ -119,7 +119,34 @@ def sanitize_address(addr, encoding): | ||||
|     return formataddr((nm, addr)) | ||||
|  | ||||
|  | ||||
| class SafeMIMEText(MIMEText): | ||||
| class MIMEMixin(): | ||||
|     def as_string(self, unixfrom=False): | ||||
|         """Return the entire formatted message as a string. | ||||
|         Optional `unixfrom' when True, means include the Unix From_ envelope | ||||
|         header. | ||||
|  | ||||
|         This overrides the default as_string() implementation to not mangle | ||||
|         lines that begin with 'From '. See bug #13433 for details. | ||||
|         """ | ||||
|         # Using a normal Generator on python 3 will yield a string, which will | ||||
|         # get base64 encoded in some cases to ensure that it's always convertable | ||||
|         # to ascii. We don't want base64 encoded emails, so we use a BytesGenertor | ||||
|         # which will do the right thing and then decode according to our known | ||||
|         # encoding. See #21093 and #3472 for details. | ||||
|         if six.PY3 and sys.version_info >= (3, 3, 3): | ||||
|             fp = six.BytesIO() | ||||
|             g = generator.BytesGenerator(fp, mangle_from_=False) | ||||
|             g.flatten(self, unixfrom=unixfrom) | ||||
|             encoding = self.get_charset().get_output_charset() if self.get_charset() else 'utf-8' | ||||
|             return fp.getvalue().decode(encoding) | ||||
|         else: | ||||
|             fp = six.StringIO() | ||||
|             g = generator.Generator(fp, mangle_from_=False) | ||||
|             g.flatten(self, unixfrom=unixfrom) | ||||
|             return fp.getvalue() | ||||
|  | ||||
|  | ||||
| class SafeMIMEText(MIMEMixin, MIMEText): | ||||
|  | ||||
|     def __init__(self, text, subtype, charset): | ||||
|         self.encoding = charset | ||||
| @@ -129,24 +156,8 @@ class SafeMIMEText(MIMEText): | ||||
|         name, val = forbid_multi_line_headers(name, val, self.encoding) | ||||
|         MIMEText.__setitem__(self, name, val) | ||||
|  | ||||
|     def as_string(self, unixfrom=False): | ||||
|         """Return the entire formatted message as a string. | ||||
|         Optional `unixfrom' when True, means include the Unix From_ envelope | ||||
|         header. | ||||
|  | ||||
|         This overrides the default as_string() implementation to not mangle | ||||
|         lines that begin with 'From '. See bug #13433 for details. | ||||
|         """ | ||||
|         fp = six.StringIO() | ||||
|         g = Generator(fp, mangle_from_ = False) | ||||
|         if sys.version_info < (2, 6, 6) and isinstance(self._payload, six.text_type): | ||||
|             # Workaround for http://bugs.python.org/issue1368247 | ||||
|             self._payload = self._payload.encode(self._charset.output_charset) | ||||
|         g.flatten(self, unixfrom=unixfrom) | ||||
|         return fp.getvalue() | ||||
|  | ||||
|  | ||||
| class SafeMIMEMultipart(MIMEMultipart): | ||||
| class SafeMIMEMultipart(MIMEMixin, MIMEMultipart): | ||||
|  | ||||
|     def __init__(self, _subtype='mixed', boundary=None, _subparts=None, encoding=None, **_params): | ||||
|         self.encoding = encoding | ||||
| @@ -156,19 +167,6 @@ class SafeMIMEMultipart(MIMEMultipart): | ||||
|         name, val = forbid_multi_line_headers(name, val, self.encoding) | ||||
|         MIMEMultipart.__setitem__(self, name, val) | ||||
|  | ||||
|     def as_string(self, unixfrom=False): | ||||
|         """Return the entire formatted message as a string. | ||||
|         Optional `unixfrom' when True, means include the Unix From_ envelope | ||||
|         header. | ||||
|  | ||||
|         This overrides the default as_string() implementation to not mangle | ||||
|         lines that begin with 'From '. See bug #13433 for details. | ||||
|         """ | ||||
|         fp = six.StringIO() | ||||
|         g = Generator(fp, mangle_from_ = False) | ||||
|         g.flatten(self, unixfrom=unixfrom) | ||||
|         return fp.getvalue() | ||||
|  | ||||
|  | ||||
| class EmailMessage(object): | ||||
|     """ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user