mirror of
https://github.com/python/cpython.git
synced 2025-07-30 14:44:10 +00:00
Issue #1670765: Prevent email.generator.Generator from re-wrapping
headers in multipart/signed MIME parts, which fixes one of the sources of invalid modifications to such parts by Generator. Patch and tests by Martin von Gagern.
This commit is contained in:
parent
57cd8ebc20
commit
ed44dfa4c7
4 changed files with 86 additions and 0 deletions
|
@ -237,6 +237,17 @@ class Generator:
|
||||||
print >> self._fp
|
print >> self._fp
|
||||||
self._fp.write(msg.epilogue)
|
self._fp.write(msg.epilogue)
|
||||||
|
|
||||||
|
def _handle_multipart_signed(self, msg):
|
||||||
|
# The contents of signed parts has to stay unmodified in order to keep
|
||||||
|
# the signature intact per RFC1847 2.1, so we disable header wrapping.
|
||||||
|
# RDM: This isn't enough to completely preserve the part, but it helps.
|
||||||
|
old_maxheaderlen = self._maxheaderlen
|
||||||
|
try:
|
||||||
|
self._maxheaderlen = 0
|
||||||
|
self._handle_multipart(msg)
|
||||||
|
finally:
|
||||||
|
self._maxheaderlen = old_maxheaderlen
|
||||||
|
|
||||||
def _handle_message_delivery_status(self, msg):
|
def _handle_message_delivery_status(self, msg):
|
||||||
# We can't just write the headers directly to self's file object
|
# We can't just write the headers directly to self's file object
|
||||||
# because this will leave an extra newline between the last header
|
# because this will leave an extra newline between the last header
|
||||||
|
|
33
Lib/email/test/data/msg_45.txt
Normal file
33
Lib/email/test/data/msg_45.txt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
From: <foo@bar.baz>
|
||||||
|
To: <baz@bar.foo>
|
||||||
|
Subject: test
|
||||||
|
X-Long-Line: Some really long line contains a lot of text and thus has to be rewrapped because it is some
|
||||||
|
really long
|
||||||
|
line
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: multipart/signed; boundary="borderline";
|
||||||
|
protocol="application/pgp-signature"; micalg=pgp-sha1
|
||||||
|
|
||||||
|
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
|
||||||
|
--borderline
|
||||||
|
Content-Type: text/plain
|
||||||
|
X-Long-Line: Another really long line contains a lot of text and thus has to be rewrapped because it is another
|
||||||
|
really long
|
||||||
|
line
|
||||||
|
|
||||||
|
This is the signed contents.
|
||||||
|
|
||||||
|
--borderline
|
||||||
|
Content-Type: application/pgp-signature; name="signature.asc"
|
||||||
|
Content-Description: OpenPGP digital signature
|
||||||
|
Content-Disposition: attachment; filename="signature.asc"
|
||||||
|
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
Version: GnuPG v2.0.6 (GNU/Linux)
|
||||||
|
|
||||||
|
iD8DBQFG03voRhp6o4m9dFsRApSZAKCCAN3IkJlVRg6NvAiMHlvvIuMGPQCeLZtj
|
||||||
|
FGwfnRHFBFO/S4/DKysm0lI=
|
||||||
|
=t7+s
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
|
||||||
|
--borderline--
|
|
@ -3275,6 +3275,42 @@ Content-Type: application/x-foo;
|
||||||
eq(s, 'My Document For You')
|
eq(s, 'My Document For You')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Tests to ensure that signed parts of an email are completely preserved, as
|
||||||
|
# required by RFC1847 section 2.1. Note that these are incomplete, because the
|
||||||
|
# email package does not currently always preserve the body. See issue 96843.
|
||||||
|
class TestSigned(TestEmailBase):
|
||||||
|
|
||||||
|
def _msg_and_obj(self, filename):
|
||||||
|
fp = openfile(findfile(filename))
|
||||||
|
try:
|
||||||
|
original = fp.read()
|
||||||
|
msg = email.message_from_string(original)
|
||||||
|
finally:
|
||||||
|
fp.close()
|
||||||
|
return original, msg
|
||||||
|
|
||||||
|
def _signed_parts_eq(self, original, result):
|
||||||
|
# Extract the first mime part of each message
|
||||||
|
import re
|
||||||
|
repart = re.compile(r'^--([^\n]+)\n(.*?)\n--\1$', re.S | re.M)
|
||||||
|
inpart = repart.search(original).group(2)
|
||||||
|
outpart = repart.search(result).group(2)
|
||||||
|
self.assertEqual(outpart, inpart)
|
||||||
|
|
||||||
|
def test_long_headers_as_string(self):
|
||||||
|
original, msg = self._msg_and_obj('msg_45.txt')
|
||||||
|
result = msg.as_string()
|
||||||
|
self._signed_parts_eq(original, result)
|
||||||
|
|
||||||
|
def test_long_headers_flatten(self):
|
||||||
|
original, msg = self._msg_and_obj('msg_45.txt')
|
||||||
|
fp = StringIO()
|
||||||
|
Generator(fp).flatten(msg)
|
||||||
|
result = fp.getvalue()
|
||||||
|
self._signed_parts_eq(original, result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _testclasses():
|
def _testclasses():
|
||||||
mod = sys.modules[__name__]
|
mod = sys.modules[__name__]
|
||||||
|
|
|
@ -30,9 +30,14 @@ Core and Builtins
|
||||||
|
|
||||||
- Issue #1967: Backport dictionary views from Python 3.x.
|
- Issue #1967: Backport dictionary views from Python 3.x.
|
||||||
|
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #1670765: Prevent email.generator.Generator from re-wrapping
|
||||||
|
headers in multipart/signed MIME parts, which fixes one of the sources of
|
||||||
|
invalid modifications to such parts by Generator.
|
||||||
|
|
||||||
- Issue #7701: Fix crash in binascii.b2a_uu() in debug mode when given a
|
- Issue #7701: Fix crash in binascii.b2a_uu() in debug mode when given a
|
||||||
1-byte argument. Patch by Victor Stinner.
|
1-byte argument. Patch by Victor Stinner.
|
||||||
|
|
||||||
|
@ -53,6 +58,7 @@ Library
|
||||||
Extension extra options may change the output without changing the .c
|
Extension extra options may change the output without changing the .c
|
||||||
file). Initial patch by Collin Winter.
|
file). Initial patch by Collin Winter.
|
||||||
|
|
||||||
|
|
||||||
Build
|
Build
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue