]> granicus.if.org Git - python/commitdiff
#1693546: don't add quotes around RFC 2231 encoded values.
authorR. David Murray <rdmurray@bitdance.com>
Fri, 24 Dec 2010 22:36:49 +0000 (22:36 +0000)
committerR. David Murray <rdmurray@bitdance.com>
Fri, 24 Dec 2010 22:36:49 +0000 (22:36 +0000)
The RFC is bit hard to understand on this point, but the examples
clearly show that parameter values that are encoded according
to its charset/language rules don't have surrounding quotes, and
the ABNF does not allow for quotes.  So when we produce such
encoded values, we no longer add quotes.

Lib/email/message.py
Lib/email/test/test_email.py
Misc/NEWS

index 8d68c093cc95f608bc269d67a8f9ba313e6ffcff..d2483cacf69a9850d79655e9cd375ac157f18f05 100644 (file)
@@ -66,17 +66,19 @@ def _formatparam(param, value=None, quote=True):
     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.  RFC 2231 encoded values are never quoted, per RFC.
         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):
index 53c4042479322a1d04feb077ab549e47f7cb90c5..73ac3470e70300a0360b0760ca1712db397f64c0 100644 (file)
@@ -534,7 +534,7 @@ class TestMessageAPI(TestEmailBase):
         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,7 +542,23 @@ class TestMessageAPI(TestEmailBase):
         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'])
 
 
@@ -3643,7 +3659,7 @@ To: bbb@zzz.org
 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 @@ To: bbb@zzz.org
 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,32 @@ Do you like this message?
         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')
+        self.assertEqual(m, msg.as_string())
+
+    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')
+        self.assertEqual(m, msg.as_string())
+
     def test_rfc2231_no_language_or_charset(self):
         m = '''\
 Content-Transfer-Encoding: 8bit
index 313fc36ddbe5a98cbc3fed352342193c73182c4c..7b6d2d11c2f697f92bba5e2b7217cacc7d5c0aac 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -11,6 +11,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #1693546: fix email.message RFC 2231 parameter encoding to be in better
+  compliance (no "s around encoded values).
+
 - Improved the diff message in the unittest module's assertCountEqual().
 
 - Issue #1155362: email.utils.parsedate_tz now handles a missing space before