mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +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 @@ def _handle_multipart(self, msg):
 | 
			
		|||
            print >> self._fp
 | 
			
		||||
            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):
 | 
			
		||||
        # We can't just write the headers directly to self's file object
 | 
			
		||||
        # 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 @@ def test_rfc2231_unencoded_then_encoded_segments(self):
 | 
			
		|||
        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():
 | 
			
		||||
    mod = sys.modules[__name__]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,9 +30,14 @@ Core and Builtins
 | 
			
		|||
 | 
			
		||||
- Issue #1967: Backport dictionary views from Python 3.x.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  1-byte argument.  Patch by Victor Stinner.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +58,7 @@ Library
 | 
			
		|||
  Extension extra options may change the output without changing the .c
 | 
			
		||||
  file). Initial patch by Collin Winter.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Build
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue