]> granicus.if.org Git - python/commitdiff
decode_rfc2231(): Be more robust against buggy RFC 2231 encodings.
authorBarry Warsaw <barry@python.org>
Mon, 17 Jul 2006 23:07:51 +0000 (23:07 +0000)
committerBarry Warsaw <barry@python.org>
Mon, 17 Jul 2006 23:07:51 +0000 (23:07 +0000)
Specifically, instead of raising a ValueError when there is a single tick in
the parameter, simply return that the entire string unquoted, with None for
both the charset and the language.  Also, if there are more than 2 ticks in
the parameter, interpret the first three parts as the standard RFC 2231 parts,
then the rest of the parts as the encoded string.

Test cases added.

Original fewer-than-3-parts fix by Tokio Kikuchi.

Resolves SF bug # 1218081.  I will back port the fix and tests to Python 2.4
(email 3.0) and Python 2.3 (email 2.5).

Also, bump the version number to email 4.0.1, removing the 'alpha' moniker.

Lib/email/__init__.py
Lib/email/test/test_email_renamed.py
Lib/email/utils.py

index f01260f57f52366a6f78ae4c2face64fb27dcdb9..8d230fdeb7d0300d7e331b2c58eb54910fd28837 100644 (file)
@@ -4,7 +4,7 @@
 
 """A package for parsing, handling, and generating email messages."""
 
-__version__ = '4.0a2'
+__version__ = '4.0.1'
 
 __all__ = [
     # Old names
index 95d06cb66f11e1b0b10d55152e6d69d0764b4ac7..4cfca6679c86f42c670ef7d456b9c4fd0bf4cbe2 100644 (file)
@@ -3060,6 +3060,40 @@ Content-Disposition: inline; filename*0=X-UNKNOWN''myfile.txt
         msg = email.message_from_string(m)
         self.assertEqual(msg.get_filename(), 'myfile.txt')
 
+    def test_rfc2231_single_tick_in_filename(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, None)
+        eq(language, None)
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_tick_attack(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo;
+\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
+
+"""
+        msg = email.message_from_string(m)
+        charset, language, s = msg.get_param('name')
+        eq(charset, 'us-ascii')
+        eq(language, 'en-us')
+        eq(s, "Frank's Document")
+
+    def test_rfc2231_no_extended_values(self):
+        eq = self.assertEqual
+        m = """\
+Content-Type: application/x-foo; name=\"Frank's Document\"
+
+"""
+        msg = email.message_from_string(m)
+        eq(msg.get_param('name'), "Frank's Document")
+
 
 \f
 def _testclasses():
index 250eb19d930922a76b6a47fba897ddee25c53ef2..ea59c27d52c9fc9936760672e3f47237b40ca873 100644 (file)
@@ -45,6 +45,7 @@ COMMASPACE = ', '
 EMPTYSTRING = ''
 UEMPTYSTRING = u''
 CRLF = '\r\n'
+TICK = "'"
 
 specialsre = re.compile(r'[][\\()<>@,:;".]')
 escapesre = re.compile(r'[][\\()"]')
@@ -231,10 +232,14 @@ def unquote(str):
 def decode_rfc2231(s):
     """Decode string according to RFC 2231"""
     import urllib
-    parts = s.split("'", 2)
-    if len(parts) == 1:
+    parts = s.split(TICK, 2)
+    if len(parts) <= 2:
         return None, None, urllib.unquote(s)
-    charset, language, s = parts
+    if len(parts) > 3:
+        charset, language = parts[:2]
+        s = TICK.join(parts[2:])
+    else:
+        charset, language, s = parts
     return charset, language, urllib.unquote(s)