]> granicus.if.org Git - python/commitdiff
#3196: if needed pad a short base64 encoded word before trying to decode.
authorR. David Murray <rdmurray@bitdance.com>
Tue, 3 Aug 2010 22:14:10 +0000 (22:14 +0000)
committerR. David Murray <rdmurray@bitdance.com>
Tue, 3 Aug 2010 22:14:10 +0000 (22:14 +0000)
The RFCs encourage following Postel's law: be liberal in what you accept.
So if someone forgot to pad the base64 encoded word payload to an
even four bytes, we add the padding before handing it to base64mime.decode.
Previously, missing padding resulted in a HeaderParseError.

Patch by Jason Williams.

Lib/email/header.py
Lib/email/test/test_email.py
Misc/ACKS
Misc/NEWS

index c924d3a7227cb204d311f072fa089f77a7661ed4..89c139105221d91fd8be6be99b5810a6f2061a0f 100644 (file)
@@ -94,6 +94,9 @@ def decode_header(header):
             word = email.quoprimime.header_decode(encoded_string)
             decoded_words.append((word, charset))
         elif encoding == 'b':
+            paderr = len(encoded_string) % 4   # Postel's law: add missing padding
+            if paderr:
+                encoded_string += '==='[:4 - paderr]
             try:
                 word = email.base64mime.decode(encoded_string)
             except binascii.Error:
index 09f51dfaca6fffc7e6eebc08f7944aff12718f2a..c3114695d1b389c3dcee62f9da0b1e050de04346 100644 (file)
@@ -1649,6 +1649,15 @@ Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar =?mac-iceland?q?r=8Aksm?=
                               (b'rg', None), (b'\xe5', 'iso-8859-1'),
                               (b'sbord', None)])
 
+    def test_rfc2047_B_bad_padding(self):
+        s = '=?iso-8859-1?B?%s?='
+        data = [                                # only test complete bytes
+            ('dm==', b'v'), ('dm=', b'v'), ('dm', b'v'),
+            ('dmk=', b'vi'), ('dmk', b'vi')
+          ]
+        for q, a in data:
+            dh = decode_header(s % q)
+            self.assertEqual(dh, [(a, 'iso-8859-1')])
 
 \f
 # Test the MIMEMessage class
@@ -3176,7 +3185,7 @@ A very long line that must get split to something other than at the
 
     def test_broken_base64_header(self):
         raises = self.assertRaises
-        s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3IQ?='
+        s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3I ?='
         raises(errors.HeaderParseError, decode_header, s)
 
 
index 0347f6755dc6c21d8ecd45b08d92472d6a8a0eb1..75c3ae7b30ec603248ac565e3eaf377390c93934 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -854,6 +854,7 @@ Felix Wiemann
 Gerry Wiener
 Frank Wierzbicki
 Bryce "Zooko" Wilcox-O'Hearn
+Jason Williams
 John Williams
 Sue Williams
 Gerald S. Williams
index a523b8fddf297dacadab15eea55daa633c4e0e3e..dcf2b624b03cd95db59345537a97f7e71ca9c683 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -37,6 +37,9 @@ Extensions
 Library
 -------
 
+- Issue #3196: email header decoding is now forgiving if an RFC2047
+  encoded word encoded in base64 is lacking padding.
+
 - Issue #9444: Argparse now uses the first element of prefix_chars as
   the option character for the added 'h/help' option if prefix_chars
   does not contain a '-', instead of raising an error.