7
7
__all__ = ['Message' , 'EmailMessage' ]
8
8
9
9
import re
10
- import uu
11
10
import quopri
12
11
from io import BytesIO , StringIO
13
12
@@ -101,6 +100,35 @@ def _unquotevalue(value):
101
100
return utils .unquote (value )
102
101
103
102
103
+ def _decode_uu (encoded ):
104
+ """Decode uuencoded data."""
105
+ decoded_lines = []
106
+ encoded_lines_iter = iter (encoded .splitlines ())
107
+ for line in encoded_lines_iter :
108
+ if line .startswith (b"begin " ):
109
+ mode , _ , path = line .removeprefix (b"begin " ).partition (b" " )
110
+ try :
111
+ int (mode , base = 8 )
112
+ except ValueError :
113
+ continue
114
+ else :
115
+ break
116
+ else :
117
+ raise ValueError ("`begin` line not found" )
118
+ for line in encoded_lines_iter :
119
+ if not line :
120
+ raise ValueError ("Truncated input" )
121
+ elif line .strip (b' \t \r \n \f ' ) == b'end' :
122
+ break
123
+ try :
124
+ decoded_line = binascii .a2b_uu (line )
125
+ except binascii .Error :
126
+ # Workaround for broken uuencoders by /Fredrik Lundh
127
+ nbytes = (((line [0 ]- 32 ) & 63 ) * 4 + 5 ) // 3
128
+ decoded_line = binascii .a2b_uu (line [:nbytes ])
129
+ decoded_lines .append (decoded_line )
130
+
131
+ return b'' .join (decoded_lines )
104
132
105
133
class Message :
106
134
"""Basic message object.
@@ -288,13 +316,10 @@ def get_payload(self, i=None, decode=False):
288
316
self .policy .handle_defect (self , defect )
289
317
return value
290
318
elif cte in ('x-uuencode' , 'uuencode' , 'uue' , 'x-uue' ):
291
- in_file = BytesIO (bpayload )
292
- out_file = BytesIO ()
293
319
try :
294
- uu .decode (in_file , out_file , quiet = True )
295
- return out_file .getvalue ()
296
- except uu .Error :
297
- # Some decoding problem
320
+ return _decode_uu (bpayload )
321
+ except ValueError :
322
+ # Some decoding problem.
298
323
return bpayload
299
324
if isinstance (payload , str ):
300
325
return bpayload
0 commit comments