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