blob: b02f86d8fb05559d51e708d31efeb7ecdb083eed [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
Victor Stinner479736b2010-05-25 21:12:34 +00005import sys
6import subprocess
Raymond Hettinger2ae87532002-05-18 00:25:10 +00007
Raymond Hettinger2ae87532002-05-18 00:25:10 +00008
Ezio Melottib3aedd42010-11-20 19:04:17 +00009
Barry Warsaw4f019d32004-01-04 01:13:02 +000010class LegacyBase64TestCase(unittest.TestCase):
Georg Brandlb54d8012009-06-04 09:11:51 +000011 def test_encodebytes(self):
Barry Warsaw4f019d32004-01-04 01:13:02 +000012 eq = self.assertEqual
Georg Brandlb54d8012009-06-04 09:11:51 +000013 eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n")
14 eq(base64.encodebytes(b"a"), b"YQ==\n")
15 eq(base64.encodebytes(b"ab"), b"YWI=\n")
16 eq(base64.encodebytes(b"abc"), b"YWJj\n")
17 eq(base64.encodebytes(b""), b"")
18 eq(base64.encodebytes(b"abcdefghijklmnopqrstuvwxyz"
Guido van Rossum4581ae52007-05-22 21:56:47 +000019 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
20 b"0123456789!@#0^&*();:<>,. []{}"),
21 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
22 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
23 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n")
Georg Brandlb54d8012009-06-04 09:11:51 +000024 self.assertRaises(TypeError, base64.encodebytes, "")
Guido van Rossumcb682582002-08-22 19:18:56 +000025
Georg Brandlb54d8012009-06-04 09:11:51 +000026 def test_decodebytes(self):
Barry Warsaw4f019d32004-01-04 01:13:02 +000027 eq = self.assertEqual
Georg Brandlb54d8012009-06-04 09:11:51 +000028 eq(base64.decodebytes(b"d3d3LnB5dGhvbi5vcmc=\n"), b"www.python.org")
29 eq(base64.decodebytes(b"YQ==\n"), b"a")
30 eq(base64.decodebytes(b"YWI=\n"), b"ab")
31 eq(base64.decodebytes(b"YWJj\n"), b"abc")
32 eq(base64.decodebytes(b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
Guido van Rossum4581ae52007-05-22 21:56:47 +000033 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
34 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"),
35 b"abcdefghijklmnopqrstuvwxyz"
36 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
37 b"0123456789!@#0^&*();:<>,. []{}")
Georg Brandlb54d8012009-06-04 09:11:51 +000038 eq(base64.decodebytes(b''), b'')
39 self.assertRaises(TypeError, base64.decodebytes, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +000040
41 def test_encode(self):
42 eq = self.assertEqual
Guido van Rossum34d19282007-08-09 01:03:29 +000043 from io import BytesIO
44 infp = BytesIO(b'abcdefghijklmnopqrstuvwxyz'
45 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
46 b'0123456789!@#0^&*();:<>,. []{}')
47 outfp = BytesIO()
Barry Warsaw4f019d32004-01-04 01:13:02 +000048 base64.encode(infp, outfp)
49 eq(outfp.getvalue(),
Guido van Rossum34d19282007-08-09 01:03:29 +000050 b'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE'
51 b'RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT'
52 b'Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n')
Barry Warsaw4f019d32004-01-04 01:13:02 +000053
54 def test_decode(self):
Guido van Rossum34d19282007-08-09 01:03:29 +000055 from io import BytesIO
56 infp = BytesIO(b'd3d3LnB5dGhvbi5vcmc=')
57 outfp = BytesIO()
Barry Warsaw4f019d32004-01-04 01:13:02 +000058 base64.decode(infp, outfp)
Guido van Rossum34d19282007-08-09 01:03:29 +000059 self.assertEqual(outfp.getvalue(), b'www.python.org')
Barry Warsaw4f019d32004-01-04 01:13:02 +000060
Ezio Melottib3aedd42010-11-20 19:04:17 +000061
Barry Warsaw4f019d32004-01-04 01:13:02 +000062class BaseXYTestCase(unittest.TestCase):
63 def test_b64encode(self):
64 eq = self.assertEqual
65 # Test default alphabet
Guido van Rossum4581ae52007-05-22 21:56:47 +000066 eq(base64.b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=")
67 eq(base64.b64encode(b'\x00'), b'AA==')
68 eq(base64.b64encode(b"a"), b"YQ==")
69 eq(base64.b64encode(b"ab"), b"YWI=")
70 eq(base64.b64encode(b"abc"), b"YWJj")
71 eq(base64.b64encode(b""), b"")
72 eq(base64.b64encode(b"abcdefghijklmnopqrstuvwxyz"
73 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
74 b"0123456789!@#0^&*();:<>,. []{}"),
75 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
76 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
77 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
Barry Warsaw4f019d32004-01-04 01:13:02 +000078 # Test with arbitrary alternative characters
Alexandre Vassalotti52098572008-05-03 04:39:38 +000079 eq(base64.b64encode(b'\xd3V\xbeo\xf7\x1d', altchars=b'*$'), b'01a*b$cd')
80 # Check if passing a str object raises an error
81 self.assertRaises(TypeError, base64.b64encode, "")
82 self.assertRaises(TypeError, base64.b64encode, b"", altchars="")
Barry Warsaw4f019d32004-01-04 01:13:02 +000083 # Test standard alphabet
Guido van Rossum4581ae52007-05-22 21:56:47 +000084 eq(base64.standard_b64encode(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=")
85 eq(base64.standard_b64encode(b"a"), b"YQ==")
86 eq(base64.standard_b64encode(b"ab"), b"YWI=")
87 eq(base64.standard_b64encode(b"abc"), b"YWJj")
88 eq(base64.standard_b64encode(b""), b"")
89 eq(base64.standard_b64encode(b"abcdefghijklmnopqrstuvwxyz"
90 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
91 b"0123456789!@#0^&*();:<>,. []{}"),
92 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
93 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT"
94 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==")
Alexandre Vassalotti52098572008-05-03 04:39:38 +000095 # Check if passing a str object raises an error
96 self.assertRaises(TypeError, base64.standard_b64encode, "")
97 self.assertRaises(TypeError, base64.standard_b64encode, b"", altchars="")
Barry Warsaw4f019d32004-01-04 01:13:02 +000098 # Test with 'URL safe' alternative characters
Guido van Rossum4581ae52007-05-22 21:56:47 +000099 eq(base64.urlsafe_b64encode(b'\xd3V\xbeo\xf7\x1d'), b'01a-b_cd')
Alexandre Vassalotti52098572008-05-03 04:39:38 +0000100 # Check if passing a str object raises an error
101 self.assertRaises(TypeError, base64.urlsafe_b64encode, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000102
103 def test_b64decode(self):
104 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100105
106 tests = {b"d3d3LnB5dGhvbi5vcmc=": b"www.python.org",
107 b'AA==': b'\x00',
108 b"YQ==": b"a",
109 b"YWI=": b"ab",
110 b"YWJj": b"abc",
111 b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE"
112 b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT"
113 b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==":
114
115 b"abcdefghijklmnopqrstuvwxyz"
116 b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
117 b"0123456789!@#0^&*();:<>,. []{}",
118 b'': b'',
119 }
120 for data, res in tests.items():
121 eq(base64.b64decode(data), res)
122 eq(base64.b64decode(data.decode('ascii')), res)
123
Barry Warsaw4f019d32004-01-04 01:13:02 +0000124 # Test with arbitrary alternative characters
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100125 tests_altchars = {(b'01a*b$cd', b'*$'): b'\xd3V\xbeo\xf7\x1d',
126 }
127 for (data, altchars), res in tests_altchars.items():
128 data_str = data.decode('ascii')
129 altchars_str = altchars.decode('ascii')
130
131 eq(base64.b64decode(data, altchars=altchars), res)
132 eq(base64.b64decode(data_str, altchars=altchars), res)
133 eq(base64.b64decode(data, altchars=altchars_str), res)
134 eq(base64.b64decode(data_str, altchars=altchars_str), res)
135
Barry Warsaw4f019d32004-01-04 01:13:02 +0000136 # Test standard alphabet
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100137 for data, res in tests.items():
138 eq(base64.standard_b64decode(data), res)
139 eq(base64.standard_b64decode(data.decode('ascii')), res)
140
Barry Warsaw4f019d32004-01-04 01:13:02 +0000141 # Test with 'URL safe' alternative characters
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100142 tests_urlsafe = {b'01a-b_cd': b'\xd3V\xbeo\xf7\x1d',
143 b'': b'',
144 }
145 for data, res in tests_urlsafe.items():
146 eq(base64.urlsafe_b64decode(data), res)
147 eq(base64.urlsafe_b64decode(data.decode('ascii')), res)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000148
R. David Murray64951362010-11-11 20:09:20 +0000149 def test_b64decode_padding_error(self):
Guido van Rossum4581ae52007-05-22 21:56:47 +0000150 self.assertRaises(binascii.Error, base64.b64decode, b'abc')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100151 self.assertRaises(binascii.Error, base64.b64decode, 'abc')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000152
R. David Murray64951362010-11-11 20:09:20 +0000153 def test_b64decode_invalid_chars(self):
154 # issue 1466065: Test some invalid characters.
155 tests = ((b'%3d==', b'\xdd'),
156 (b'$3d==', b'\xdd'),
157 (b'[==', b''),
158 (b'YW]3=', b'am'),
159 (b'3{d==', b'\xdd'),
160 (b'3d}==', b'\xdd'),
161 (b'@@', b''),
162 (b'!', b''),
163 (b'YWJj\nYWI=', b'abcab'))
164 for bstr, res in tests:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000165 self.assertEqual(base64.b64decode(bstr), res)
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100166 self.assertEqual(base64.b64decode(bstr.decode('ascii')), res)
R. David Murray64951362010-11-11 20:09:20 +0000167 with self.assertRaises(binascii.Error):
168 base64.b64decode(bstr, validate=True)
Antoine Pitroudff46fa2012-02-20 19:46:26 +0100169 with self.assertRaises(binascii.Error):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100170 base64.b64decode(bstr.decode('ascii'), validate=True)
R. David Murray64951362010-11-11 20:09:20 +0000171
Barry Warsaw4f019d32004-01-04 01:13:02 +0000172 def test_b32encode(self):
173 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000174 eq(base64.b32encode(b''), b'')
175 eq(base64.b32encode(b'\x00'), b'AA======')
176 eq(base64.b32encode(b'a'), b'ME======')
177 eq(base64.b32encode(b'ab'), b'MFRA====')
178 eq(base64.b32encode(b'abc'), b'MFRGG===')
179 eq(base64.b32encode(b'abcd'), b'MFRGGZA=')
180 eq(base64.b32encode(b'abcde'), b'MFRGGZDF')
Alexandre Vassalotti52098572008-05-03 04:39:38 +0000181 self.assertRaises(TypeError, base64.b32encode, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000182
183 def test_b32decode(self):
184 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100185 tests = {b'': b'',
186 b'AA======': b'\x00',
187 b'ME======': b'a',
188 b'MFRA====': b'ab',
189 b'MFRGG===': b'abc',
190 b'MFRGGZA=': b'abcd',
191 b'MFRGGZDF': b'abcde',
192 }
193 for data, res in tests.items():
194 eq(base64.b32decode(data), res)
195 eq(base64.b32decode(data.decode('ascii')), res)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000196
197 def test_b32decode_casefold(self):
198 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100199 tests = {b'': b'',
200 b'ME======': b'a',
201 b'MFRA====': b'ab',
202 b'MFRGG===': b'abc',
203 b'MFRGGZA=': b'abcd',
204 b'MFRGGZDF': b'abcde',
205 # Lower cases
206 b'me======': b'a',
207 b'mfra====': b'ab',
208 b'mfrgg===': b'abc',
209 b'mfrggza=': b'abcd',
210 b'mfrggzdf': b'abcde',
211 }
212
213 for data, res in tests.items():
214 eq(base64.b32decode(data, True), res)
215 eq(base64.b32decode(data.decode('ascii'), True), res)
216
Guido van Rossum4581ae52007-05-22 21:56:47 +0000217 self.assertRaises(TypeError, base64.b32decode, b'me======')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100218 self.assertRaises(TypeError, base64.b32decode, 'me======')
219
Barry Warsaw4f019d32004-01-04 01:13:02 +0000220 # Mapping zero and one
Guido van Rossum4581ae52007-05-22 21:56:47 +0000221 eq(base64.b32decode(b'MLO23456'), b'b\xdd\xad\xf3\xbe')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100222 eq(base64.b32decode('MLO23456'), b'b\xdd\xad\xf3\xbe')
223
224 map_tests = {(b'M1023456', b'L'): b'b\xdd\xad\xf3\xbe',
225 (b'M1023456', b'I'): b'b\x1d\xad\xf3\xbe',
226 }
227 for (data, map01), res in map_tests.items():
228 data_str = data.decode('ascii')
229 map01_str = map01.decode('ascii')
230
231 eq(base64.b32decode(data, map01=map01), res)
232 eq(base64.b32decode(data_str, map01=map01), res)
233 eq(base64.b32decode(data, map01=map01_str), res)
234 eq(base64.b32decode(data_str, map01=map01_str), res)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000235
236 def test_b32decode_error(self):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100237 for data in [b'abc', b'ABCDEF==']:
238 with self.assertRaises(binascii.Error):
239 base64.b32decode(data)
Antoine Pitroudff46fa2012-02-20 19:46:26 +0100240 with self.assertRaises(binascii.Error):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100241 base64.b32decode(data.decode('ascii'))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000242
243 def test_b16encode(self):
244 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000245 eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF')
246 eq(base64.b16encode(b'\x00'), b'00')
Alexandre Vassalotti52098572008-05-03 04:39:38 +0000247 self.assertRaises(TypeError, base64.b16encode, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000248
249 def test_b16decode(self):
250 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000251 eq(base64.b16decode(b'0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100252 eq(base64.b16decode('0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000253 eq(base64.b16decode(b'00'), b'\x00')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100254 eq(base64.b16decode('00'), b'\x00')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000255 # Lower case is not allowed without a flag
Guido van Rossum4581ae52007-05-22 21:56:47 +0000256 self.assertRaises(binascii.Error, base64.b16decode, b'0102abcdef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100257 self.assertRaises(binascii.Error, base64.b16decode, '0102abcdef')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000258 # Case fold
Guido van Rossum4581ae52007-05-22 21:56:47 +0000259 eq(base64.b16decode(b'0102abcdef', True), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100260 eq(base64.b16decode('0102abcdef', True), b'\x01\x02\xab\xcd\xef')
261
262 def test_decode_nonascii_str(self):
263 decode_funcs = (base64.b64decode,
264 base64.standard_b64decode,
265 base64.urlsafe_b64decode,
266 base64.b32decode,
267 base64.b16decode)
268 for f in decode_funcs:
269 self.assertRaises(ValueError, f, 'with non-ascii \xcb')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000270
271 def test_ErrorHeritage(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000272 self.assertTrue(issubclass(binascii.Error, ValueError))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000273
274
Ezio Melottib3aedd42010-11-20 19:04:17 +0000275
Victor Stinner479736b2010-05-25 21:12:34 +0000276class TestMain(unittest.TestCase):
277 def get_output(self, *args, **options):
278 args = (sys.executable, '-m', 'base64') + args
279 return subprocess.check_output(args, **options)
280
281 def test_encode_decode(self):
282 output = self.get_output('-t')
283 self.assertSequenceEqual(output.splitlines(), (
284 b"b'Aladdin:open sesame'",
285 br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'",
286 b"b'Aladdin:open sesame'",
287 ))
288
289 def test_encode_file(self):
290 with open(support.TESTFN, 'wb') as fp:
291 fp.write(b'a\xffb\n')
292
293 output = self.get_output('-e', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000294 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000295
296 with open(support.TESTFN, 'rb') as fp:
297 output = self.get_output('-e', stdin=fp)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000298 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000299
300 def test_decode(self):
301 with open(support.TESTFN, 'wb') as fp:
302 fp.write(b'Yf9iCg==')
303 output = self.get_output('-d', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000304 self.assertEqual(output.rstrip(), b'a\xffb')
Victor Stinner479736b2010-05-25 21:12:34 +0000305
306
Ezio Melottib3aedd42010-11-20 19:04:17 +0000307
Raymond Hettinger2ae87532002-05-18 00:25:10 +0000308def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000309 support.run_unittest(__name__)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000310
311if __name__ == '__main__':
Guido van Rossumd8faa362007-04-27 19:54:29 +0000312 test_main()