Index: Lib/email/test/test_email.py =================================================================== --- Lib/email/test/test_email.py (revision 87451) +++ Lib/email/test/test_email.py (working copy) @@ -534,7 +534,7 @@ msg.add_header('Content-Disposition', 'attachment', filename="Fußballer.ppt") self.assertEqual( - 'attachment; filename*="utf-8\'\'Fu%C3%9Fballer.ppt"', + 'attachment; filename*=utf-8\'\'Fu%C3%9Fballer.ppt', msg['Content-Disposition']) def test_nonascii_add_header_via_triple(self): @@ -542,10 +542,26 @@ msg.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', '', 'Fußballer.ppt')) self.assertEqual( - 'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"', + 'attachment; filename*=iso-8859-1\'\'Fu%DFballer.ppt', msg['Content-Disposition']) + def test_ascii_add_header_with_tspecial(self): + msg = Message() + msg.add_header('Content-Disposition', 'attachment', + filename="windows [filename].ppt") + self.assertEqual( + 'attachment; filename="windows [filename].ppt"', + msg['Content-Disposition']) + def test_nonascii_add_header_with_tspecial(self): + msg = Message() + msg.add_header('Content-Disposition', 'attachment', + filename="Fußballer [filename].ppt") + self.assertEqual( + "attachment; filename*=utf-8''Fu%C3%9Fballer%20%5Bfilename%5D.ppt", + msg['Content-Disposition']) + + # Test the email.encoders module class TestEncoders(unittest.TestCase): def test_encode_empty_payload(self): @@ -3643,7 +3659,7 @@ Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Content-Type: text/plain; charset=us-ascii; - title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" + title*=us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21 Hi, @@ -3673,7 +3689,7 @@ Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Content-Type: text/plain; charset="us-ascii"; - title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" + title*=us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21 Hi, @@ -3688,6 +3704,30 @@ msg = self._msgobj('msg_32.txt') eq(msg.get_content_charset(), 'us-ascii') + def test_rfc2231_parse_rfc_quoting(self): + m = textwrap.dedent('''\ + Content-Disposition: inline; + \tfilename*0*=''This%20is%20even%20more%20; + \tfilename*1*=%2A%2A%2Afun%2A%2A%2A%20; + \tfilename*2="is it not.pdf" + + ''') + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + + def test_rfc2231_parse_extra_quoting(self): + m = textwrap.dedent('''\ + Content-Disposition: inline; + \tfilename*0*="''This%20is%20even%20more%20"; + \tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; + \tfilename*2="is it not.pdf" + + ''') + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + def test_rfc2231_no_language_or_charset(self): m = '''\ Content-Transfer-Encoding: 8bit Index: Lib/email/message.py =================================================================== --- Lib/email/message.py (revision 87446) +++ Lib/email/message.py (working copy) @@ -66,17 +66,21 @@ if value is not None and len(value) > 0: # A tuple is used for RFC 2231 encoded parameter values where items # are (charset, language, value). charset is a string, not a Charset - # instance. + # instance. If RFC 2231 encoding is used, the value cannot contain + # any characters that would otherwise need quoting, so per the RFC + # we never quote those values. if isinstance(value, tuple): # Encode as per RFC 2231 param += '*' value = utils.encode_rfc2231(value[2], value[0], value[1]) + return "%s=%s" % (param, value) else: try: value.encode('ascii') except UnicodeEncodeError: param += '*' value = utils.encode_rfc2231(value, 'utf-8', '') + return "%s=%s" % (param, value) # BAW: Please check this. I think that if quote is set it should # force quoting even if not necessary. if quote or tspecials.search(value):