summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorR. David Murray <rdmurray@bitdance.com>2010-12-24 22:36:49 (GMT)
committerR. David Murray <rdmurray@bitdance.com>2010-12-24 22:36:49 (GMT)
commitdfd7eb0ba2f3296f28028970e395e38f3ae9eedc (patch)
tree02ded19904da4eeea1f27afcaf6b042734348188
parentddf53709eedd94450cc95c3ea0758c621790193d (diff)
downloadcpython-dfd7eb0ba2f3296f28028970e395e38f3ae9eedc.zip
cpython-dfd7eb0ba2f3296f28028970e395e38f3ae9eedc.tar.gz
cpython-dfd7eb0ba2f3296f28028970e395e38f3ae9eedc.tar.bz2
#1693546: don't add quotes around RFC 2231 encoded values.
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.
-rw-r--r--Lib/email/message.py4
-rw-r--r--Lib/email/test/test_email.py50
-rw-r--r--Misc/NEWS3
3 files changed, 52 insertions, 5 deletions
diff --git a/Lib/email/message.py b/Lib/email/message.py
index 8d68c09..d2483ca 100644
--- a/Lib/email/message.py
+++ b/Lib/email/message.py
@@ -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):
diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py
index 53c4042..73ac347 100644
--- a/Lib/email/test/test_email.py
+++ b/Lib/email/test/test_email.py
@@ -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
diff --git a/Misc/NEWS b/Misc/NEWS
index 313fc36..7b6d2d1 100644
--- 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