summaryrefslogtreecommitdiffstats
path: root/Lib/email
diff options
context:
space:
mode:
authorR David Murray <rdmurray@bitdance.com>2014-02-08 16:48:20 (GMT)
committerR David Murray <rdmurray@bitdance.com>2014-02-08 16:48:20 (GMT)
commit905c8c3d8dfe081d91e399aa5fd93d1659655264 (patch)
tree898bc50c4048cc85caddcd74af36237e0768475e /Lib/email
parent7c389e2404b97b5e48c02e2735229eef30e3f1cf (diff)
downloadcpython-905c8c3d8dfe081d91e399aa5fd93d1659655264.zip
cpython-905c8c3d8dfe081d91e399aa5fd93d1659655264.tar.gz
cpython-905c8c3d8dfe081d91e399aa5fd93d1659655264.tar.bz2
#19772: Do not mutate message when downcoding to 7bit.
This is a bit of an ugly hack because of the way generator pieces together the output message. The deepcopys aren't too expensive, though, because we know it is only called on messages that are not multiparts, and the payload (the thing that could be large) is an immutable object. Test and preliminary work on patch by Vajrasky Kok.
Diffstat (limited to 'Lib/email')
-rw-r--r--Lib/email/generator.py14
1 files changed, 14 insertions, 0 deletions
diff --git a/Lib/email/generator.py b/Lib/email/generator.py
index 4ea0b55..07a97c7 100644
--- a/Lib/email/generator.py
+++ b/Lib/email/generator.py
@@ -12,6 +12,7 @@ import time
import random
import warnings
+from copy import deepcopy
from io import StringIO, BytesIO
from email._policybase import compat32
from email.header import Header
@@ -173,10 +174,18 @@ class Generator:
# necessary.
oldfp = self._fp
try:
+ self._munge_cte = None
self._fp = sfp = self._new_buffer()
self._dispatch(msg)
finally:
self._fp = oldfp
+ munge_cte = self._munge_cte
+ del self._munge_cte
+ # If we munged the cte, copy the message again and re-fix the CTE.
+ if munge_cte:
+ msg = deepcopy(msg)
+ msg.replace_header('content-transfer-encoding', munge_cte[0])
+ msg.replace_header('content-type', munge_cte[1])
# Write the headers. First we see if the message object wants to
# handle that itself. If not, we'll do it generically.
meth = getattr(msg, '_write_headers', None)
@@ -225,9 +234,14 @@ class Generator:
if _has_surrogates(msg._payload):
charset = msg.get_param('charset')
if charset is not None:
+ # XXX: This copy stuff is an ugly hack to avoid modifying the
+ # existing message.
+ msg = deepcopy(msg)
del msg['content-transfer-encoding']
msg.set_payload(payload, charset)
payload = msg.get_payload()
+ self._munge_cte = (msg['content-transfer-encoding'],
+ msg['content-type'])
if self._mangle_from_:
payload = fcre.sub('>From ', payload)
self._write_lines(payload)