[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:
parent
2d08390d70
commit
35a447a263
|
@ -5,8 +5,8 @@ import os
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from email import generator
|
||||||
from email import charset as Charset, encoders as Encoders
|
from email import charset as Charset, encoders as Encoders
|
||||||
from email.generator import Generator
|
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
|
@ -119,7 +119,34 @@ def sanitize_address(addr, encoding):
|
||||||
return formataddr((nm, addr))
|
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):
|
def __init__(self, text, subtype, charset):
|
||||||
self.encoding = charset
|
self.encoding = charset
|
||||||
|
@ -129,24 +156,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)
|
|
||||||
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):
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -156,19 +167,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