blob: b9738ddaf5ba23d3b10c1276e01a0969a2c60ffa [file] [log] [blame]
Walter Dörwald21d3a322003-05-01 17:45:56 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Walter Dörwald21d3a322003-05-01 17:45:56 +00003import base64
Guido van Rossum4581ae52007-05-22 21:56:47 +00004import binascii
Vinay Sajipf9596182012-03-02 01:01:13 +00005import os
Victor Stinner479736b2010-05-25 21:12:34 +00006import sys
7import subprocess
Nick Coghlanfdf239a2013-10-03 00:43:22 +10008import struct
9from array import array
Raymond Hettinger2ae87532002-05-18 00:25:10 +000010
Ezio Melottib3aedd42010-11-20 19:04:17 +000011
Barry Warsaw4f019d32004-01-04 01:13:02 +000012class LegacyBase64TestCase(unittest.TestCase):
Nick Coghlanfdf239a2013-10-03 00:43:22 +100013
14 # Legacy API is not as permissive as the modern API
15 def check_type_errors(self, f):
16 self.assertRaises(TypeError, f, "")
17 self.assertRaises(TypeError, f, [])
18 multidimensional = memoryview(b"1234").cast('B', (2, 2))
19 self.assertRaises(TypeError, f, multidimensional)
20 int_data = memoryview(b"1234").cast('I')
21 self.assertRaises(TypeError, f, int_data)
22
Georg Brandlb54d8012009-06-04 09:11:51 +000023 def test_encodebytes(self):
Barry Warsaw4f019d32004-01-04 01:13:02 +000024 eq = self.assertEqual
Georg Brandlb54d8012009-06-04 09:11:51 +000025 eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n")
26 eq(base64.encodebytes(b"a"), b"YQ==\n")
27 eq(base64.encodebytes(b"ab"), b"YWI=\n")
28 eq(base64.encodebytes(b"abc"), b"YWJj\n")
29 eq(base64.encodebytes(b""), b"")
30 eq(base64.encodebytes(b"abcdefghijklmnopqrstuvwxyz"
Guido van Rossum4581ae52007-05-22 21:56:47 +000031 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
32 b"0123456789!@#0^&*();:<>,. []{}"),
33 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
34 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
35 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n")
Serhiy Storchaka017523c2013-04-28 15:53:08 +030036 # Non-bytes
37 eq(base64.encodebytes(bytearray(b'abc')), b'YWJj\n')
Nick Coghlanfdf239a2013-10-03 00:43:22 +100038 eq(base64.encodebytes(memoryview(b'abc')), b'YWJj\n')
39 eq(base64.encodebytes(array('B', b'abc')), b'YWJj\n')
40 self.check_type_errors(base64.encodebytes)
Guido van Rossumcb682582002-08-22 19:18:56 +000041
Georg Brandlb54d8012009-06-04 09:11:51 +000042 def test_decodebytes(self):
Barry Warsaw4f019d32004-01-04 01:13:02 +000043 eq = self.assertEqual
Georg Brandlb54d8012009-06-04 09:11:51 +000044 eq(base64.decodebytes(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org")
45 eq(base64.decodebytes(b"YQ==\n"), b"a")
46 eq(base64.decodebytes(b"YWI=\n"), b"ab")
47 eq(base64.decodebytes(b"YWJj\n"), b"abc")
48 eq(base64.decodebytes(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
Guido van Rossum4581ae52007-05-22 21:56:47 +000049 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
50 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"),
51 b"abcdefghijklmnopqrstuvwxyz"
52 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
53 b"0123456789!@#0^&*();:<>,. []{}")
Georg Brandlb54d8012009-06-04 09:11:51 +000054 eq(base64.decodebytes(b''), b'')
Serhiy Storchaka017523c2013-04-28 15:53:08 +030055 # Non-bytes
56 eq(base64.decodebytes(bytearray(b'YWJj\n')), b'abc')
Nick Coghlanfdf239a2013-10-03 00:43:22 +100057 eq(base64.decodebytes(memoryview(b'YWJj\n')), b'abc')
58 eq(base64.decodebytes(array('B', b'YWJj\n')), b'abc')
59 self.check_type_errors(base64.decodebytes)
Barry Warsaw4f019d32004-01-04 01:13:02 +000060
61 def test_encode(self):
62 eq = self.assertEqual
Serhiy Storchakaabac0a72013-04-28 15:56:11 +030063 from io import BytesIO, StringIO
Guido van Rossum34d19282007-08-09 01:03:29 +000064 infp = BytesIO(b'abcdefghijklmnopqrstuvwxyz'
65 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
66 b'0123456789!@#0^&*();:<>,. []{}')
67 outfp = BytesIO()
Barry Warsaw4f019d32004-01-04 01:13:02 +000068 base64.encode(infp, outfp)
69 eq(outfp.getvalue(),
Guido van Rossum34d19282007-08-09 01:03:29 +000070 b'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE'
71 b'RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT'
72 b'Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n')
Serhiy Storchakaabac0a72013-04-28 15:56:11 +030073 # Non-binary files
74 self.assertRaises(TypeError, base64.encode, StringIO('abc'), BytesIO())
75 self.assertRaises(TypeError, base64.encode, BytesIO(b'abc'), StringIO())
76 self.assertRaises(TypeError, base64.encode, StringIO('abc'), StringIO())
Barry Warsaw4f019d32004-01-04 01:13:02 +000077
78 def test_decode(self):
Serhiy Storchakaabac0a72013-04-28 15:56:11 +030079 from io import BytesIO, StringIO
Guido van Rossum34d19282007-08-09 01:03:29 +000080 infp = BytesIO(b'd3d3LnB5dGhvbi5vcmc=')
81 outfp = BytesIO()
Barry Warsaw4f019d32004-01-04 01:13:02 +000082 base64.decode(infp, outfp)
Guido van Rossum34d19282007-08-09 01:03:29 +000083 self.assertEqual(outfp.getvalue(), b'www.python.org')
Serhiy Storchakaabac0a72013-04-28 15:56:11 +030084 # Non-binary files
85 self.assertRaises(TypeError, base64.encode, StringIO('YWJj\n'), BytesIO())
86 self.assertRaises(TypeError, base64.encode, BytesIO(b'YWJj\n'), StringIO())
87 self.assertRaises(TypeError, base64.encode, StringIO('YWJj\n'), StringIO())
Barry Warsaw4f019d32004-01-04 01:13:02 +000088
Ezio Melottib3aedd42010-11-20 19:04:17 +000089
Barry Warsaw4f019d32004-01-04 01:13:02 +000090class BaseXYTestCase(unittest.TestCase):
Nick Coghlanfdf239a2013-10-03 00:43:22 +100091
92 # Modern API completely ignores exported dimension and format data and
93 # treats any buffer as a stream of bytes
94 def check_encode_type_errors(self, f):
95 self.assertRaises(TypeError, f, "")
96 self.assertRaises(TypeError, f, [])
97
98 def check_decode_type_errors(self, f):
99 self.assertRaises(TypeError, f, [])
100
101 def check_other_types(self, f, bytes_data, expected):
102 eq = self.assertEqual
Antoine Pitrou6dd0d462013-11-17 23:52:25 +0100103 b = bytearray(bytes_data)
104 eq(f(b), expected)
105 # The bytearray wasn't mutated
106 eq(b, bytes_data)
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000107 eq(f(memoryview(bytes_data)), expected)
108 eq(f(array('B', bytes_data)), expected)
Antoine Pitrou6dd0d462013-11-17 23:52:25 +0100109 # XXX why is b64encode hardcoded here?
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000110 self.check_nonbyte_element_format(base64.b64encode, bytes_data)
111 self.check_multidimensional(base64.b64encode, bytes_data)
112
113 def check_multidimensional(self, f, data):
114 padding = b"\x00" if len(data) % 2 else b""
115 bytes_data = data + padding # Make sure cast works
116 shape = (len(bytes_data) // 2, 2)
117 multidimensional = memoryview(bytes_data).cast('B', shape)
118 self.assertEqual(f(multidimensional), f(bytes_data))
119
120 def check_nonbyte_element_format(self, f, data):
121 padding = b"\x00" * ((4 - len(data)) % 4)
122 bytes_data = data + padding # Make sure cast works
123 int_data = memoryview(bytes_data).cast('I')
124 self.assertEqual(f(int_data), f(bytes_data))
125
126
Barry Warsaw4f019d32004-01-04 01:13:02 +0000127 def test_b64encode(self):
128 eq = self.assertEqual
129 # Test default alphabet
Guido van Rossum4581ae52007-05-22 21:56:47 +0000130 eq(base64.b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=")
131 eq(base64.b64encode(b'\x00'), b'AA==')
132 eq(base64.b64encode(b"a"), b"YQ==")
133 eq(base64.b64encode(b"ab"), b"YWI=")
134 eq(base64.b64encode(b"abc"), b"YWJj")
135 eq(base64.b64encode(b""), b"")
136 eq(base64.b64encode(b"abcdefghijklmnopqrstuvwxyz"
137 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
138 b"0123456789!@#0^&*();:<>,. []{}"),
139 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
140 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
141 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000142 # Test with arbitrary alternative characters
Alexandre Vassalotti5209857f2008-05-03 04:39:38 +0000143 eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=b'*$'), b'01a*b$cd')
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300144 eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=bytearray(b'*$')),
145 b'01a*b$cd')
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000146 eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=memoryview(b'*$')),
147 b'01a*b$cd')
148 eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=array('B', b'*$')),
149 b'01a*b$cd')
150 # Non-bytes
151 self.check_other_types(base64.b64encode, b'abcd', b'YWJjZA==')
152 self.check_encode_type_errors(base64.b64encode)
153 self.assertRaises(TypeError, base64.b64encode, b"", altchars="*$")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000154 # Test standard alphabet
Guido van Rossum4581ae52007-05-22 21:56:47 +0000155 eq(base64.standard_b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=")
156 eq(base64.standard_b64encode(b"a"), b"YQ==")
157 eq(base64.standard_b64encode(b"ab"), b"YWI=")
158 eq(base64.standard_b64encode(b"abc"), b"YWJj")
159 eq(base64.standard_b64encode(b""), b"")
160 eq(base64.standard_b64encode(b"abcdefghijklmnopqrstuvwxyz"
161 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
162 b"0123456789!@#0^&*();:<>,. []{}"),
163 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
164 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
165 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300166 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000167 self.check_other_types(base64.standard_b64encode,
168 b'abcd', b'YWJjZA==')
169 self.check_encode_type_errors(base64.standard_b64encode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000170 # Test with 'URL safe' alternative characters
Guido van Rossum4581ae52007-05-22 21:56:47 +0000171 eq(base64.urlsafe_b64encode(b'\xd3V\xbeo\xf7\x1d'), b'01a-b_cd')
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300172 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000173 self.check_other_types(base64.urlsafe_b64encode,
174 b'\xd3V\xbeo\xf7\x1d', b'01a-b_cd')
175 self.check_encode_type_errors(base64.urlsafe_b64encode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000176
177 def test_b64decode(self):
178 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100179
180 tests = {b"d3d3LnB5dGhvbi5vcmc=": b"www.python.org",
181 b'AA==': b'\x00',
182 b"YQ==": b"a",
183 b"YWI=": b"ab",
184 b"YWJj": b"abc",
185 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
186 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
187 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==":
188
189 b"abcdefghijklmnopqrstuvwxyz"
190 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
191 b"0123456789!@#0^&*();:<>,. []{}",
192 b'': b'',
193 }
194 for data, res in tests.items():
195 eq(base64.b64decode(data), res)
196 eq(base64.b64decode(data.decode('ascii')), res)
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300197 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000198 self.check_other_types(base64.b64decode, b"YWJj", b"abc")
199 self.check_decode_type_errors(base64.b64decode)
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100200
Barry Warsaw4f019d32004-01-04 01:13:02 +0000201 # Test with arbitrary alternative characters
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100202 tests_altchars = {(b'01a*b$cd', b'*$'): b'\xd3V\xbeo\xf7\x1d',
203 }
204 for (data, altchars), res in tests_altchars.items():
205 data_str = data.decode('ascii')
206 altchars_str = altchars.decode('ascii')
207
208 eq(base64.b64decode(data, altchars=altchars), res)
209 eq(base64.b64decode(data_str, altchars=altchars), res)
210 eq(base64.b64decode(data, altchars=altchars_str), res)
211 eq(base64.b64decode(data_str, altchars=altchars_str), res)
212
Barry Warsaw4f019d32004-01-04 01:13:02 +0000213 # Test standard alphabet
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100214 for data, res in tests.items():
215 eq(base64.standard_b64decode(data), res)
216 eq(base64.standard_b64decode(data.decode('ascii')), res)
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300217 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000218 self.check_other_types(base64.standard_b64decode, b"YWJj", b"abc")
219 self.check_decode_type_errors(base64.standard_b64decode)
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100220
Barry Warsaw4f019d32004-01-04 01:13:02 +0000221 # Test with 'URL safe' alternative characters
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100222 tests_urlsafe = {b'01a-b_cd': b'\xd3V\xbeo\xf7\x1d',
223 b'': b'',
224 }
225 for data, res in tests_urlsafe.items():
226 eq(base64.urlsafe_b64decode(data), res)
227 eq(base64.urlsafe_b64decode(data.decode('ascii')), res)
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300228 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000229 self.check_other_types(base64.urlsafe_b64decode, b'01a-b_cd',
230 b'\xd3V\xbeo\xf7\x1d')
231 self.check_decode_type_errors(base64.urlsafe_b64decode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000232
R. David Murray64951362010-11-11 20:09:20 +0000233 def test_b64decode_padding_error(self):
Guido van Rossum4581ae52007-05-22 21:56:47 +0000234 self.assertRaises(binascii.Error, base64.b64decode, b'abc')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100235 self.assertRaises(binascii.Error, base64.b64decode, 'abc')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000236
R. David Murray64951362010-11-11 20:09:20 +0000237 def test_b64decode_invalid_chars(self):
238 # issue 1466065: Test some invalid characters.
239 tests = ((b'%3d==', b'\xdd'),
240 (b'$3d==', b'\xdd'),
241 (b'[==', b''),
242 (b'YW]3=', b'am'),
243 (b'3{d==', b'\xdd'),
244 (b'3d}==', b'\xdd'),
245 (b'@@', b''),
246 (b'!', b''),
247 (b'YWJj\nYWI=', b'abcab'))
248 for bstr, res in tests:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000249 self.assertEqual(base64.b64decode(bstr), res)
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100250 self.assertEqual(base64.b64decode(bstr.decode('ascii')), res)
R. David Murray64951362010-11-11 20:09:20 +0000251 with self.assertRaises(binascii.Error):
252 base64.b64decode(bstr, validate=True)
Antoine Pitroudff46fa2012-02-20 19:46:26 +0100253 with self.assertRaises(binascii.Error):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100254 base64.b64decode(bstr.decode('ascii'), validate=True)
R. David Murray64951362010-11-11 20:09:20 +0000255
Barry Warsaw4f019d32004-01-04 01:13:02 +0000256 def test_b32encode(self):
257 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000258 eq(base64.b32encode(b''), b'')
259 eq(base64.b32encode(b'\x00'), b'AA======')
260 eq(base64.b32encode(b'a'), b'ME======')
261 eq(base64.b32encode(b'ab'), b'MFRA====')
262 eq(base64.b32encode(b'abc'), b'MFRGG===')
263 eq(base64.b32encode(b'abcd'), b'MFRGGZA=')
264 eq(base64.b32encode(b'abcde'), b'MFRGGZDF')
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300265 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000266 self.check_other_types(base64.b32encode, b'abcd', b'MFRGGZA=')
267 self.check_encode_type_errors(base64.b32encode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000268
269 def test_b32decode(self):
270 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100271 tests = {b'': b'',
272 b'AA======': b'\x00',
273 b'ME======': b'a',
274 b'MFRA====': b'ab',
275 b'MFRGG===': b'abc',
276 b'MFRGGZA=': b'abcd',
277 b'MFRGGZDF': b'abcde',
278 }
279 for data, res in tests.items():
280 eq(base64.b32decode(data), res)
281 eq(base64.b32decode(data.decode('ascii')), res)
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300282 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000283 self.check_other_types(base64.b32decode, b'MFRGG===', b"abc")
284 self.check_decode_type_errors(base64.b32decode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000285
286 def test_b32decode_casefold(self):
287 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100288 tests = {b'': b'',
289 b'ME======': b'a',
290 b'MFRA====': b'ab',
291 b'MFRGG===': b'abc',
292 b'MFRGGZA=': b'abcd',
293 b'MFRGGZDF': b'abcde',
294 # Lower cases
295 b'me======': b'a',
296 b'mfra====': b'ab',
297 b'mfrgg===': b'abc',
298 b'mfrggza=': b'abcd',
299 b'mfrggzdf': b'abcde',
300 }
301
302 for data, res in tests.items():
303 eq(base64.b32decode(data, True), res)
304 eq(base64.b32decode(data.decode('ascii'), True), res)
305
Serhiy Storchakaea2b4902013-05-28 15:27:29 +0300306 self.assertRaises(binascii.Error, base64.b32decode, b'me======')
307 self.assertRaises(binascii.Error, base64.b32decode, 'me======')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100308
Barry Warsaw4f019d32004-01-04 01:13:02 +0000309 # Mapping zero and one
Guido van Rossum4581ae52007-05-22 21:56:47 +0000310 eq(base64.b32decode(b'MLO23456'), b'b\xdd\xad\xf3\xbe')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100311 eq(base64.b32decode('MLO23456'), b'b\xdd\xad\xf3\xbe')
312
313 map_tests = {(b'M1023456', b'L'): b'b\xdd\xad\xf3\xbe',
314 (b'M1023456', b'I'): b'b\x1d\xad\xf3\xbe',
315 }
316 for (data, map01), res in map_tests.items():
317 data_str = data.decode('ascii')
318 map01_str = map01.decode('ascii')
319
320 eq(base64.b32decode(data, map01=map01), res)
321 eq(base64.b32decode(data_str, map01=map01), res)
322 eq(base64.b32decode(data, map01=map01_str), res)
323 eq(base64.b32decode(data_str, map01=map01_str), res)
Serhiy Storchakaea2b4902013-05-28 15:27:29 +0300324 self.assertRaises(binascii.Error, base64.b32decode, data)
325 self.assertRaises(binascii.Error, base64.b32decode, data_str)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000326
327 def test_b32decode_error(self):
Serhiy Storchakaea2b4902013-05-28 15:27:29 +0300328 for data in [b'abc', b'ABCDEF==', b'==ABCDEF']:
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100329 with self.assertRaises(binascii.Error):
330 base64.b32decode(data)
Antoine Pitroudff46fa2012-02-20 19:46:26 +0100331 with self.assertRaises(binascii.Error):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100332 base64.b32decode(data.decode('ascii'))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000333
334 def test_b16encode(self):
335 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000336 eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF')
337 eq(base64.b16encode(b'\x00'), b'00')
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300338 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000339 self.check_other_types(base64.b16encode, b'\x01\x02\xab\xcd\xef',
340 b'0102ABCDEF')
341 self.check_encode_type_errors(base64.b16encode)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000342
343 def test_b16decode(self):
344 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000345 eq(base64.b16decode(b'0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100346 eq(base64.b16decode('0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000347 eq(base64.b16decode(b'00'), b'\x00')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100348 eq(base64.b16decode('00'), b'\x00')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000349 # Lower case is not allowed without a flag
Guido van Rossum4581ae52007-05-22 21:56:47 +0000350 self.assertRaises(binascii.Error, base64.b16decode, b'0102abcdef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100351 self.assertRaises(binascii.Error, base64.b16decode, '0102abcdef')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000352 # Case fold
Guido van Rossum4581ae52007-05-22 21:56:47 +0000353 eq(base64.b16decode(b'0102abcdef', True), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100354 eq(base64.b16decode('0102abcdef', True), b'\x01\x02\xab\xcd\xef')
Serhiy Storchaka017523c2013-04-28 15:53:08 +0300355 # Non-bytes
Nick Coghlanfdf239a2013-10-03 00:43:22 +1000356 self.check_other_types(base64.b16decode, b"0102ABCDEF",
357 b'\x01\x02\xab\xcd\xef')
358 self.check_decode_type_errors(base64.b16decode)
359 eq(base64.b16decode(bytearray(b"0102abcdef"), True),
360 b'\x01\x02\xab\xcd\xef')
361 eq(base64.b16decode(memoryview(b"0102abcdef"), True),
362 b'\x01\x02\xab\xcd\xef')
363 eq(base64.b16decode(array('B', b"0102abcdef"), True),
364 b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100365
Antoine Pitrou6dd0d462013-11-17 23:52:25 +0100366 def test_a85encode(self):
367 eq = self.assertEqual
368
369 tests = {
370 b'': b'',
371 b"www.python.org": b'GB\\6`E-ZP=Df.1GEb>',
372 bytes(range(255)): b"""!!*-'"9eu7#RLhG$k3[W&.oNg'GVB"(`=52*$$"""
373 b"""(B+<_pR,UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm5X@_(6q'R884cE"""
374 b"""H9MJ8X:f1+h<)lt#=BSg3>[:ZC?t!MSA7]@cBPD3sCi+'.E,fo>FEMbN"""
375 b"""G^4U^I!pHnJ:W<)KS>/9Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7DTV8*TU"""
376 b"""nsrdW2ZetXKAY/Yd(L?['d?O\\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd"""
377 b"""*^:jeCE.%f\\,!5gtgiEi8N\\UjQ5OekiqBum-X60nF?)@o_%qPq"ad`"""
378 b"""r;HT""",
379 b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
380 b"0123456789!@#0^&*();:<>,. []{}":
381 b'@:E_WAS,RgBkhF"D/O92EH6,BF`qtRH$VbC6UX@47n?3D92&&T'
382 b":Jand;cHat='/U/0JP==1c70M3&r-I,;<FN.OZ`-3]oSW/g+A(H[P",
383 b"no padding..": b'DJpY:@:Wn_DJ(RS',
384 b"zero compression\0\0\0\0": b'H=_,8+Cf>,E,oN2F(oQ1z',
385 b"zero compression\0\0\0": b'H=_,8+Cf>,E,oN2F(oQ1!!!!',
386 b"Boundary:\0\0\0\0": b'6>q!aA79M(3WK-[!!',
387 b"Space compr: ": b';fH/TAKYK$D/aMV+<VdL',
388 b'\xff': b'rr',
389 b'\xff'*2: b's8N',
390 b'\xff'*3: b's8W*',
391 b'\xff'*4: b's8W-!',
392 }
393
394 for data, res in tests.items():
395 eq(base64.a85encode(data), res, data)
396 eq(base64.a85encode(data, adobe=False), res, data)
397 eq(base64.a85encode(data, adobe=True), b'<~' + res + b'~>', data)
398
399 self.check_other_types(base64.a85encode, b"www.python.org",
400 b'GB\\6`E-ZP=Df.1GEb>')
401
402 self.assertRaises(TypeError, base64.a85encode, "")
403
404 eq(base64.a85encode(b"www.python.org", wrapcol=7, adobe=False),
405 b'GB\\6`E-\nZP=Df.1\nGEb>')
406 eq(base64.a85encode(b"\0\0\0\0www.python.org", wrapcol=7, adobe=False),
407 b'zGB\\6`E\n-ZP=Df.\n1GEb>')
408 eq(base64.a85encode(b"www.python.org", wrapcol=7, adobe=True),
409 b'<~GB\\6`\nE-ZP=Df\n.1GEb>\n~>')
410
411 eq(base64.a85encode(b' '*8, foldspaces=True, adobe=False), b'yy')
412 eq(base64.a85encode(b' '*7, foldspaces=True, adobe=False), b'y+<Vd')
413 eq(base64.a85encode(b' '*6, foldspaces=True, adobe=False), b'y+<U')
414 eq(base64.a85encode(b' '*5, foldspaces=True, adobe=False), b'y+9')
415
416 def test_b85encode(self):
417 eq = self.assertEqual
418
419 tests = {
420 b'': b'',
421 b'www.python.org': b'cXxL#aCvlSZ*DGca%T',
422 bytes(range(255)): b"""009C61O)~M2nh-c3=Iws5D^j+6crX17#SKH9337X"""
423 b"""AR!_nBqb&%C@Cr{EG;fCFflSSG&MFiI5|2yJUu=?KtV!7L`6nNNJ&ad"""
424 b"""OifNtP*GA-R8>}2SXo+ITwPvYU}0ioWMyV&XlZI|Y;A6DaB*^Tbai%j"""
425 b"""czJqze0_d@fPsR8goTEOh>41ejE#<ukdcy;l$Dm3n3<ZJoSmMZprN9p"""
426 b"""q@|{(sHv)}tgWuEu(7hUw6(UkxVgH!yuH4^z`?@9#Kp$P$jQpf%+1cv"""
427 b"""(9zP<)YaD4*xB0K+}+;a;Njxq<mKk)=;`X~?CtLF@bU8V^!4`l`1$(#"""
428 b"""{Qdp""",
429 b"""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"""
430 b"""0123456789!@#0^&*();:<>,. []{}""":
431 b"""VPa!sWoBn+X=-b1ZEkOHadLBXb#`}nd3r%YLqtVJM@UIZOH55pPf$@("""
432 b"""Q&d$}S6EqEFflSSG&MFiI5{CeBQRbjDkv#CIy^osE+AW7dwl""",
433 b'no padding..': b'Zf_uPVPs@!Zf7no',
434 b'zero compression\x00\x00\x00\x00': b'dS!BNAY*TBaB^jHb7^mG00000',
435 b'zero compression\x00\x00\x00': b'dS!BNAY*TBaB^jHb7^mG0000',
436 b"""Boundary:\x00\x00\x00\x00""": b"""LT`0$WMOi7IsgCw00""",
437 b'Space compr: ': b'Q*dEpWgug3ZE$irARr(h',
438 b'\xff': b'{{',
439 b'\xff'*2: b'|Nj',
440 b'\xff'*3: b'|Ns9',
441 b'\xff'*4: b'|NsC0',
442 }
443
444 for data, res in tests.items():
445 eq(base64.b85encode(data), res)
446
447 self.check_other_types(base64.b85encode, b"www.python.org",
448 b'cXxL#aCvlSZ*DGca%T')
449
450 def test_a85decode(self):
451 eq = self.assertEqual
452
453 tests = {
454 b'': b'',
455 b'GB\\6`E-ZP=Df.1GEb>': b'www.python.org',
456 b"""! ! * -'"\n\t\t9eu\r\n7# RL\vhG$k3[W&.oNg'GVB"(`=52*$$"""
457 b"""(B+<_pR,UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm5X@_(6q'R884cE"""
458 b"""H9MJ8X:f1+h<)lt#=BSg3>[:ZC?t!MSA7]@cBPD3sCi+'.E,fo>FEMbN"""
459 b"""G^4U^I!pHnJ:W<)KS>/9Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7DTV8*TU"""
460 b"""nsrdW2ZetXKAY/Yd(L?['d?O\\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd"""
461 b"""*^:jeCE.%f\\,!5gtgiEi8N\\UjQ5OekiqBum-X60nF?)@o_%qPq"ad`"""
462 b"""r;HT""": bytes(range(255)),
463 b"""@:E_WAS,RgBkhF"D/O92EH6,BF`qtRH$VbC6UX@47n?3D92&&T:Jand;c"""
464 b"""Hat='/U/0JP==1c70M3&r-I,;<FN.OZ`-3]oSW/g+A(H[P""":
465 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234'
466 b'56789!@#0^&*();:<>,. []{}',
467 b'DJpY:@:Wn_DJ(RS': b'no padding..',
468 b'H=_,8+Cf>,E,oN2F(oQ1z': b'zero compression\x00\x00\x00\x00',
469 b'H=_,8+Cf>,E,oN2F(oQ1!!!!': b'zero compression\x00\x00\x00',
470 b'6>q!aA79M(3WK-[!!': b"Boundary:\x00\x00\x00\x00",
471 b';fH/TAKYK$D/aMV+<VdL': b'Space compr: ',
472 b'rr': b'\xff',
473 b's8N': b'\xff'*2,
474 b's8W*': b'\xff'*3,
475 b's8W-!': b'\xff'*4,
476 }
477
478 for data, res in tests.items():
479 eq(base64.a85decode(data), res, data)
480 eq(base64.a85decode(data, adobe=False), res, data)
481 eq(base64.a85decode(data.decode("ascii"), adobe=False), res, data)
482 eq(base64.a85decode(b'<~' + data + b'~>', adobe=True), res, data)
483 eq(base64.a85decode('<~%s~>' % data.decode("ascii"), adobe=True),
484 res, data)
485
486 eq(base64.a85decode(b'yy', foldspaces=True, adobe=False), b' '*8)
487 eq(base64.a85decode(b'y+<Vd', foldspaces=True, adobe=False), b' '*7)
488 eq(base64.a85decode(b'y+<U', foldspaces=True, adobe=False), b' '*6)
489 eq(base64.a85decode(b'y+9', foldspaces=True, adobe=False), b' '*5)
490
491 self.check_other_types(base64.a85decode, b'GB\\6`E-ZP=Df.1GEb>',
492 b"www.python.org")
493
494 def test_b85decode(self):
495 eq = self.assertEqual
496
497 tests = {
498 b'': b'',
499 b'cXxL#aCvlSZ*DGca%T': b'www.python.org',
500 b"""009C61O)~M2nh-c3=Iws5D^j+6crX17#SKH9337X"""
501 b"""AR!_nBqb&%C@Cr{EG;fCFflSSG&MFiI5|2yJUu=?KtV!7L`6nNNJ&ad"""
502 b"""OifNtP*GA-R8>}2SXo+ITwPvYU}0ioWMyV&XlZI|Y;A6DaB*^Tbai%j"""
503 b"""czJqze0_d@fPsR8goTEOh>41ejE#<ukdcy;l$Dm3n3<ZJoSmMZprN9p"""
504 b"""q@|{(sHv)}tgWuEu(7hUw6(UkxVgH!yuH4^z`?@9#Kp$P$jQpf%+1cv"""
505 b"""(9zP<)YaD4*xB0K+}+;a;Njxq<mKk)=;`X~?CtLF@bU8V^!4`l`1$(#"""
506 b"""{Qdp""": bytes(range(255)),
507 b"""VPa!sWoBn+X=-b1ZEkOHadLBXb#`}nd3r%YLqtVJM@UIZOH55pPf$@("""
508 b"""Q&d$}S6EqEFflSSG&MFiI5{CeBQRbjDkv#CIy^osE+AW7dwl""":
509 b"""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"""
510 b"""0123456789!@#0^&*();:<>,. []{}""",
511 b'Zf_uPVPs@!Zf7no': b'no padding..',
512 b'dS!BNAY*TBaB^jHb7^mG00000': b'zero compression\x00\x00\x00\x00',
513 b'dS!BNAY*TBaB^jHb7^mG0000': b'zero compression\x00\x00\x00',
514 b"""LT`0$WMOi7IsgCw00""": b"""Boundary:\x00\x00\x00\x00""",
515 b'Q*dEpWgug3ZE$irARr(h': b'Space compr: ',
516 b'{{': b'\xff',
517 b'|Nj': b'\xff'*2,
518 b'|Ns9': b'\xff'*3,
519 b'|NsC0': b'\xff'*4,
520 }
521
522 for data, res in tests.items():
523 eq(base64.b85decode(data), res)
524 eq(base64.b85decode(data.decode("ascii")), res)
525
526 self.check_other_types(base64.b85decode, b'cXxL#aCvlSZ*DGca%T',
527 b"www.python.org")
528
529 def test_a85_padding(self):
530 eq = self.assertEqual
531
532 eq(base64.a85encode(b"x", pad=True), b'GQ7^D')
533 eq(base64.a85encode(b"xx", pad=True), b"G^'2g")
534 eq(base64.a85encode(b"xxx", pad=True), b'G^+H5')
535 eq(base64.a85encode(b"xxxx", pad=True), b'G^+IX')
536 eq(base64.a85encode(b"xxxxx", pad=True), b'G^+IXGQ7^D')
537
538 eq(base64.a85decode(b'GQ7^D'), b"x\x00\x00\x00")
539 eq(base64.a85decode(b"G^'2g"), b"xx\x00\x00")
540 eq(base64.a85decode(b'G^+H5'), b"xxx\x00")
541 eq(base64.a85decode(b'G^+IX'), b"xxxx")
542 eq(base64.a85decode(b'G^+IXGQ7^D'), b"xxxxx\x00\x00\x00")
543
544 def test_b85_padding(self):
545 eq = self.assertEqual
546
547 eq(base64.b85encode(b"x", pad=True), b'cmMzZ')
548 eq(base64.b85encode(b"xx", pad=True), b'cz6H+')
549 eq(base64.b85encode(b"xxx", pad=True), b'czAdK')
550 eq(base64.b85encode(b"xxxx", pad=True), b'czAet')
551 eq(base64.b85encode(b"xxxxx", pad=True), b'czAetcmMzZ')
552
553 eq(base64.b85decode(b'cmMzZ'), b"x\x00\x00\x00")
554 eq(base64.b85decode(b'cz6H+'), b"xx\x00\x00")
555 eq(base64.b85decode(b'czAdK'), b"xxx\x00")
556 eq(base64.b85decode(b'czAet'), b"xxxx")
557 eq(base64.b85decode(b'czAetcmMzZ'), b"xxxxx\x00\x00\x00")
558
559 def test_a85decode_errors(self):
560 illegal = (set(range(32)) | set(range(118, 256))) - set(b' \t\n\r\v')
561 for c in illegal:
562 with self.assertRaises(ValueError, msg=bytes([c])):
563 base64.a85decode(b'!!!!' + bytes([c]))
564 with self.assertRaises(ValueError, msg=bytes([c])):
565 base64.a85decode(b'!!!!' + bytes([c]), adobe=False)
566 with self.assertRaises(ValueError, msg=bytes([c])):
567 base64.a85decode(b'<~!!!!' + bytes([c]) + b'~>', adobe=True)
568
569 self.assertRaises(ValueError, base64.a85decode,
570 b"malformed", adobe=True)
571 self.assertRaises(ValueError, base64.a85decode,
572 b"<~still malformed", adobe=True)
573 self.assertRaises(ValueError, base64.a85decode,
574 b"also malformed~>", adobe=True)
575
576 # With adobe=False (the default), Adobe framing markers are disallowed
577 self.assertRaises(ValueError, base64.a85decode,
578 b"<~~>")
579 self.assertRaises(ValueError, base64.a85decode,
580 b"<~~>", adobe=False)
581 base64.a85decode(b"<~~>", adobe=True) # sanity check
582
583 self.assertRaises(ValueError, base64.a85decode,
584 b"abcx", adobe=False)
585 self.assertRaises(ValueError, base64.a85decode,
586 b"abcdey", adobe=False)
587 self.assertRaises(ValueError, base64.a85decode,
588 b"a b\nc", adobe=False, ignorechars=b"")
589
590 self.assertRaises(ValueError, base64.a85decode, b's', adobe=False)
591 self.assertRaises(ValueError, base64.a85decode, b's8', adobe=False)
592 self.assertRaises(ValueError, base64.a85decode, b's8W', adobe=False)
593 self.assertRaises(ValueError, base64.a85decode, b's8W-', adobe=False)
594 self.assertRaises(ValueError, base64.a85decode, b's8W-"', adobe=False)
595
596 def test_b85decode_errors(self):
597 illegal = list(range(33)) + \
598 list(b'"\',./:[\\]') + \
599 list(range(128, 256))
600 for c in illegal:
601 with self.assertRaises(ValueError, msg=bytes([c])):
602 base64.b85decode(b'0000' + bytes([c]))
603
604 self.assertRaises(ValueError, base64.b85decode, b'|')
605 self.assertRaises(ValueError, base64.b85decode, b'|N')
606 self.assertRaises(ValueError, base64.b85decode, b'|Ns')
607 self.assertRaises(ValueError, base64.b85decode, b'|NsC')
608 self.assertRaises(ValueError, base64.b85decode, b'|NsC1')
609
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100610 def test_decode_nonascii_str(self):
611 decode_funcs = (base64.b64decode,
612 base64.standard_b64decode,
613 base64.urlsafe_b64decode,
614 base64.b32decode,
Antoine Pitrou6dd0d462013-11-17 23:52:25 +0100615 base64.b16decode,
616 base64.b85decode,
617 base64.a85decode)
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100618 for f in decode_funcs:
619 self.assertRaises(ValueError, f, 'with non-ascii \xcb')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000620
621 def test_ErrorHeritage(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000622 self.assertTrue(issubclass(binascii.Error, ValueError))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000623
624
Ezio Melottib3aedd42010-11-20 19:04:17 +0000625
Victor Stinner479736b2010-05-25 21:12:34 +0000626class TestMain(unittest.TestCase):
Vinay Sajipf9596182012-03-02 01:01:13 +0000627 def tearDown(self):
628 if os.path.exists(support.TESTFN):
629 os.unlink(support.TESTFN)
630
Victor Stinner479736b2010-05-25 21:12:34 +0000631 def get_output(self, *args, **options):
632 args = (sys.executable, '-m', 'base64') + args
633 return subprocess.check_output(args, **options)
634
635 def test_encode_decode(self):
636 output = self.get_output('-t')
637 self.assertSequenceEqual(output.splitlines(), (
638 b"b'Aladdin:open sesame'",
639 br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'",
640 b"b'Aladdin:open sesame'",
641 ))
642
643 def test_encode_file(self):
644 with open(support.TESTFN, 'wb') as fp:
645 fp.write(b'a\xffb\n')
646
647 output = self.get_output('-e', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000648 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000649
650 with open(support.TESTFN, 'rb') as fp:
651 output = self.get_output('-e', stdin=fp)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000652 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000653
654 def test_decode(self):
655 with open(support.TESTFN, 'wb') as fp:
656 fp.write(b'Yf9iCg==')
657 output = self.get_output('-d', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000658 self.assertEqual(output.rstrip(), b'a\xffb')
Victor Stinner479736b2010-05-25 21:12:34 +0000659
660
Ezio Melottib3aedd42010-11-20 19:04:17 +0000661
Raymond Hettinger2ae87532002-05-18 00:25:10 +0000662def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000663 support.run_unittest(__name__)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000664
665if __name__ == '__main__':
Guido van Rossumd8faa362007-04-27 19:54:29 +0000666 test_main()