diff -r e408e821d6c8 Lib/email/message.py --- a/Lib/email/message.py Sat Jul 27 02:41:48 2013 +0200 +++ b/Lib/email/message.py Sat Jul 27 13:01:59 2013 +0800 @@ -275,6 +275,28 @@ Optional charset sets the message's default character set. See set_charset() for details. """ + cte = str(self.get('content-transfer-encoding', '')).lower() + if isinstance(payload, bytes) and cte: + if cte == 'base64': + try: + decode_b(b''.join(payload.splitlines())) + except AssertionError: + raise ValueError('Can not set payload with invalid ' + 'base64 data if content transfer ' + 'encoding is base64.') + elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + in_file = BytesIO(payload) + out_file = BytesIO() + try: + uu.decode(in_file, out_file, quiet=True) + except uu.Error: + # Some decoding problem + pass + except binascii.Error: + raise ValueError('Can not set payload with invalid ' + + '%s data if content transfer ' % cte + + 'encoding is %s.' % cte) + payload = payload.decode('ascii', 'surrogateescape') self._payload = payload if charset is not None: self.set_charset(charset) diff -r e408e821d6c8 Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py Sat Jul 27 02:41:48 2013 +0200 +++ b/Lib/test/test_email/test_email.py Sat Jul 27 13:01:59 2013 +0800 @@ -593,6 +593,72 @@ "attachment; filename*=utf-8''Fu%C3%9Fballer%20%5Bfilename%5D.ppt", msg['Content-Disposition']) + def test_binary_quopri_payload(self): + def quopri_set_payload(binary_data, expected_data): + msg = Message() + msg['content-type'] = 'text/plain; charset=latin-1' + msg['content-transfer-encoding'] = 'quoted-printable' + msg.set_payload(binary_data) + self.assertEqual(msg.get_payload(decode=True), expected_data) + quopri_set_payload(b'foo=e6=96=87bar', b'foo\xe6\x96\x87bar') + quopri_set_payload(b'\x00\u1234\xff\377', b'\x00\u1234\xff\377') + quopri_set_payload(b'Hello world', b'Hello world') + quopri_set_payload(b'', b'') + quopri_set_payload(b'foo=ez6=!96=87bar', b'foo=ez6=!96\x87bar') + bytes_data = 'Fußballer.ppt'.encode('utf-8') + quopri_set_payload(bytes_data, bytes_data) + + def test_binary_base64_payload(self): + def base64_set_payload(binary_data, expected_data): + msg = Message() + msg['content-type'] = 'text/plain; charset=latin-1' + msg['content-transfer-encoding'] = 'base64' + msg.set_payload(binary_data) + self.assertEqual(msg.get_payload(decode=True), expected_data) + def base64_set_payload_raise_exception(binary_data): + msg = Message() + msg['content-type'] = 'text/plain; charset=latin-1' + msg['content-transfer-encoding'] = 'base64' + self.assertRaises(ValueError, msg.set_payload, binary_data) + base64_set_payload(b'Zm9v5paHYmFy', b'foo\xe6\x96\x87bar') + base64_set_payload(b'Hello world', b'\x1d\xe9e\xa3\n+\x95') + base64_set_payload(b'', b'') + base64_set_payload('Fußballer.ppt'.encode('utf-8'), + b'\x16\xe6\xda\x96W\xab\xa6\x9b') + base64_set_payload_raise_exception(b'Zm9h(v5pa*HYmFy') + base64_set_payload_raise_exception(b'\x00\u1234\xff\377') + + def test_binary_uuencode_payload(self): + def uuencode_set_payload(binary_data, expected_data, encoding): + msg = Message() + msg['content-type'] = 'text/plain; charset=latin-1' + msg['content-transfer-encoding'] = encoding + msg.set_payload(binary_data) + self.assertEqual(msg.get_payload(decode=True), + expected_data, + 'get_payload returns wrong result ' + 'with encoding %s.' % encoding) + def uuencode_set_payload_raise_exception(binary_data, + encoding): + msg = Message() + msg['content-type'] = 'text/plain; charset=latin-1' + msg['content-transfer-encoding'] = encoding + self.assertRaises(ValueError, msg.set_payload, binary_data) + for encoding in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + uuencode_set_payload(b"begin 666 -\n)9F]OYI:'8F%R\n \nend\n", + b'foo\xe6\x96\x87bar', + encoding) + uuencode_set_payload(b'\x00\u1234\xff\377', + b'\x00\u1234\xff\377', + encoding) + uuencode_set_payload(b'Hello world', b'Hello world', encoding) + uuencode_set_payload(b'', b'', encoding) + bytes_data = 'Fußballer.ppt'.encode('utf-8') + uuencode_set_payload(bytes_data, bytes_data, encoding) + uuencode_set_payload_raise_exception( + b"begin 777 -\n)9Z]OYI:'iF%R\n \nend\n", + encoding) + def test_add_header_with_name_only_param(self): msg = Message() msg.add_header('Content-Disposition', 'inline', foo_bar=None)