mirror of https://github.com/django/django.git
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.
This commit is contained in:
parent
b7a7baa554
commit
f28ea02308
|
@ -3,9 +3,10 @@ from __future__ import unicode_literals
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
from email import charset as Charset, encoders as Encoders, message_from_string
|
from email import (charset as Charset, encoders as Encoders,
|
||||||
from email.generator import Generator
|
message_from_string, generator)
|
||||||
from email.message import Message
|
from email.message import Message
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
@ -121,13 +122,7 @@ def sanitize_address(addr, encoding):
|
||||||
return formataddr((nm, addr))
|
return formataddr((nm, addr))
|
||||||
|
|
||||||
|
|
||||||
class SafeMIMEMessage(MIMEMessage):
|
class MIMEMixin():
|
||||||
|
|
||||||
def __setitem__(self, name, val):
|
|
||||||
# message/rfc822 attachments must be ASCII
|
|
||||||
name, val = forbid_multi_line_headers(name, val, 'ascii')
|
|
||||||
MIMEMessage.__setitem__(self, name, val)
|
|
||||||
|
|
||||||
def as_string(self, unixfrom=False):
|
def as_string(self, unixfrom=False):
|
||||||
"""Return the entire formatted message as a string.
|
"""Return the entire formatted message as a string.
|
||||||
Optional `unixfrom' when True, means include the Unix From_ envelope
|
Optional `unixfrom' when True, means include the Unix From_ envelope
|
||||||
|
@ -136,13 +131,33 @@ class SafeMIMEMessage(MIMEMessage):
|
||||||
This overrides the default as_string() implementation to not mangle
|
This overrides the default as_string() implementation to not mangle
|
||||||
lines that begin with 'From '. See bug #13433 for details.
|
lines that begin with 'From '. See bug #13433 for details.
|
||||||
"""
|
"""
|
||||||
fp = six.StringIO()
|
# Using a normal Generator on python 3 will yield a string, which will
|
||||||
g = Generator(fp, mangle_from_=False)
|
# get base64 encoded in some cases to ensure that it's always convertable
|
||||||
g.flatten(self, unixfrom=unixfrom)
|
# to ascii. We don't want base64 encoded emails, so we use a BytesGenertor
|
||||||
return fp.getvalue()
|
# 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(MIMEText):
|
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
||||||
|
|
||||||
|
def __setitem__(self, name, val):
|
||||||
|
# message/rfc822 attachments must be ASCII
|
||||||
|
name, val = forbid_multi_line_headers(name, val, 'ascii')
|
||||||
|
MIMEMessage.__setitem__(self, name, val)
|
||||||
|
|
||||||
|
|
||||||
|
class SafeMIMEText(MIMEMixin, MIMEText):
|
||||||
|
|
||||||
def __init__(self, text, subtype, charset):
|
def __init__(self, text, subtype, charset):
|
||||||
self.encoding = charset
|
self.encoding = charset
|
||||||
|
@ -161,21 +176,8 @@ class SafeMIMEText(MIMEText):
|
||||||
name, val = forbid_multi_line_headers(name, val, self.encoding)
|
name, val = forbid_multi_line_headers(name, val, self.encoding)
|
||||||
MIMEText.__setitem__(self, name, val)
|
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
|
class SafeMIMEMultipart(MIMEMixin, MIMEMultipart):
|
||||||
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 SafeMIMEMultipart(MIMEMultipart):
|
|
||||||
|
|
||||||
def __init__(self, _subtype='mixed', boundary=None, _subparts=None, encoding=None, **_params):
|
def __init__(self, _subtype='mixed', boundary=None, _subparts=None, encoding=None, **_params):
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
|
@ -185,19 +187,6 @@ class SafeMIMEMultipart(MIMEMultipart):
|
||||||
name, val = forbid_multi_line_headers(name, val, self.encoding)
|
name, val = forbid_multi_line_headers(name, val, self.encoding)
|
||||||
MIMEMultipart.__setitem__(self, name, val)
|
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):
|
class EmailMessage(object):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue