|
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