blob: 5744af40becc78a88bc9dded0416be75b9e63d47 [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 Pitrouea6b4d52012-02-20 19:30:23 +0100169 base64.b64decode(bstr.decode('ascii'), validate=True)
R. David Murray64951362010-11-11 20:09:20 +0000170
Barry Warsaw4f019d32004-01-04 01:13:02 +0000171 def test_b32encode(self):
172 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000173 eq(base64.b32encode(b''), b'')
174 eq(base64.b32encode(b'\x00'), b'AA======')
175 eq(base64.b32encode(b'a'), b'ME======')
176 eq(base64.b32encode(b'ab'), b'MFRA====')
177 eq(base64.b32encode(b'abc'), b'MFRGG===')
178 eq(base64.b32encode(b'abcd'), b'MFRGGZA=')
179 eq(base64.b32encode(b'abcde'), b'MFRGGZDF')
Alexandre Vassalotti52098572008-05-03 04:39:38 +0000180 self.assertRaises(TypeError, base64.b32encode, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000181
182 def test_b32decode(self):
183 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100184 tests = {b'': b'',
185 b'AA======': b'\x00',
186 b'ME======': b'a',
187 b'MFRA====': b'ab',
188 b'MFRGG===': b'abc',
189 b'MFRGGZA=': b'abcd',
190 b'MFRGGZDF': b'abcde',
191 }
192 for data, res in tests.items():
193 eq(base64.b32decode(data), res)
194 eq(base64.b32decode(data.decode('ascii')), res)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000195
196 def test_b32decode_casefold(self):
197 eq = self.assertEqual
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100198 tests = {b'': b'',
199 b'ME======': b'a',
200 b'MFRA====': b'ab',
201 b'MFRGG===': b'abc',
202 b'MFRGGZA=': b'abcd',
203 b'MFRGGZDF': b'abcde',
204 # Lower cases
205 b'me======': b'a',
206 b'mfra====': b'ab',
207 b'mfrgg===': b'abc',
208 b'mfrggza=': b'abcd',
209 b'mfrggzdf': b'abcde',
210 }
211
212 for data, res in tests.items():
213 eq(base64.b32decode(data, True), res)
214 eq(base64.b32decode(data.decode('ascii'), True), res)
215
Guido van Rossum4581ae52007-05-22 21:56:47 +0000216 self.assertRaises(TypeError, base64.b32decode, b'me======')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100217 self.assertRaises(TypeError, base64.b32decode, 'me======')
218
Barry Warsaw4f019d32004-01-04 01:13:02 +0000219 # Mapping zero and one
Guido van Rossum4581ae52007-05-22 21:56:47 +0000220 eq(base64.b32decode(b'MLO23456'), b'b\xdd\xad\xf3\xbe')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100221 eq(base64.b32decode('MLO23456'), b'b\xdd\xad\xf3\xbe')
222
223 map_tests = {(b'M1023456', b'L'): b'b\xdd\xad\xf3\xbe',
224 (b'M1023456', b'I'): b'b\x1d\xad\xf3\xbe',
225 }
226 for (data, map01), res in map_tests.items():
227 data_str = data.decode('ascii')
228 map01_str = map01.decode('ascii')
229
230 eq(base64.b32decode(data, map01=map01), res)
231 eq(base64.b32decode(data_str, map01=map01), res)
232 eq(base64.b32decode(data, map01=map01_str), res)
233 eq(base64.b32decode(data_str, map01=map01_str), res)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000234
235 def test_b32decode_error(self):
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100236 for data in [b'abc', b'ABCDEF==']:
237 with self.assertRaises(binascii.Error):
238 base64.b32decode(data)
239 base64.b32decode(data.decode('ascii'))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000240
241 def test_b16encode(self):
242 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000243 eq(base64.b16encode(b'\x01\x02\xab\xcd\xef'), b'0102ABCDEF')
244 eq(base64.b16encode(b'\x00'), b'00')
Alexandre Vassalotti52098572008-05-03 04:39:38 +0000245 self.assertRaises(TypeError, base64.b16encode, "")
Barry Warsaw4f019d32004-01-04 01:13:02 +0000246
247 def test_b16decode(self):
248 eq = self.assertEqual
Guido van Rossum4581ae52007-05-22 21:56:47 +0000249 eq(base64.b16decode(b'0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100250 eq(base64.b16decode('0102ABCDEF'), b'\x01\x02\xab\xcd\xef')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000251 eq(base64.b16decode(b'00'), b'\x00')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100252 eq(base64.b16decode('00'), b'\x00')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000253 # Lower case is not allowed without a flag
Guido van Rossum4581ae52007-05-22 21:56:47 +0000254 self.assertRaises(binascii.Error, base64.b16decode, b'0102abcdef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100255 self.assertRaises(binascii.Error, base64.b16decode, '0102abcdef')
Barry Warsaw4f019d32004-01-04 01:13:02 +0000256 # Case fold
Guido van Rossum4581ae52007-05-22 21:56:47 +0000257 eq(base64.b16decode(b'0102abcdef', True), b'\x01\x02\xab\xcd\xef')
Antoine Pitrouea6b4d52012-02-20 19:30:23 +0100258 eq(base64.b16decode('0102abcdef', True), b'\x01\x02\xab\xcd\xef')
259
260 def test_decode_nonascii_str(self):
261 decode_funcs = (base64.b64decode,
262 base64.standard_b64decode,
263 base64.urlsafe_b64decode,
264 base64.b32decode,
265 base64.b16decode)
266 for f in decode_funcs:
267 self.assertRaises(ValueError, f, 'with non-ascii \xcb')
Guido van Rossum4581ae52007-05-22 21:56:47 +0000268
269 def test_ErrorHeritage(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000270 self.assertTrue(issubclass(binascii.Error, ValueError))
Barry Warsaw4f019d32004-01-04 01:13:02 +0000271
272
Ezio Melottib3aedd42010-11-20 19:04:17 +0000273
Victor Stinner479736b2010-05-25 21:12:34 +0000274class TestMain(unittest.TestCase):
275 def get_output(self, *args, **options):
276 args = (sys.executable, '-m', 'base64') + args
277 return subprocess.check_output(args, **options)
278
279 def test_encode_decode(self):
280 output = self.get_output('-t')
281 self.assertSequenceEqual(output.splitlines(), (
282 b"b'Aladdin:open sesame'",
283 br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'",
284 b"b'Aladdin:open sesame'",
285 ))
286
287 def test_encode_file(self):
288 with open(support.TESTFN, 'wb') as fp:
289 fp.write(b'a\xffb\n')
290
291 output = self.get_output('-e', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000292 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000293
294 with open(support.TESTFN, 'rb') as fp:
295 output = self.get_output('-e', stdin=fp)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000296 self.assertEqual(output.rstrip(), b'Yf9iCg==')
Victor Stinner479736b2010-05-25 21:12:34 +0000297
298 def test_decode(self):
299 with open(support.TESTFN, 'wb') as fp:
300 fp.write(b'Yf9iCg==')
301 output = self.get_output('-d', support.TESTFN)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000302 self.assertEqual(output.rstrip(), b'a\xffb')
Victor Stinner479736b2010-05-25 21:12:34 +0000303
304
Ezio Melottib3aedd42010-11-20 19:04:17 +0000305
Raymond Hettinger2ae87532002-05-18 00:25:10 +0000306def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000307 support.run_unittest(__name__)
Barry Warsaw4f019d32004-01-04 01:13:02 +0000308
309if __name__ == '__main__':
Guido van Rossumd8faa362007-04-27 19:54:29 +0000310 test_main()