blob: bbaa9442ab76b04b657bdc1ea4498bb67e76f37e [file] [log] [blame]
Skip Montanaroc1b41542003-08-02 15:02:33 +00001# -*- coding: iso-8859-1 -*-
2
3from test import test_support
Tim Peters82112372001-08-29 02:28:42 +00004import marshal
5import sys
Skip Montanaroc1b41542003-08-02 15:02:33 +00006import unittest
7import os
Tim Peters82112372001-08-29 02:28:42 +00008
Serhiy Storchaka4068b012015-02-06 08:56:33 +02009try:
10 import _testcapi
11except ImportError:
12 _testcapi = None
13
Skip Montanaroc1b41542003-08-02 15:02:33 +000014class IntTestCase(unittest.TestCase):
15 def test_ints(self):
16 # Test the full range of Python ints.
17 n = sys.maxint
18 while n:
19 for expected in (-n, n):
20 s = marshal.dumps(expected)
21 got = marshal.loads(s)
22 self.assertEqual(expected, got)
23 marshal.dump(expected, file(test_support.TESTFN, "wb"))
24 got = marshal.load(file(test_support.TESTFN, "rb"))
25 self.assertEqual(expected, got)
26 n = n >> 1
27 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +000028
Skip Montanaroc1b41542003-08-02 15:02:33 +000029 def test_int64(self):
30 # Simulate int marshaling on a 64-bit box. This is most interesting if
31 # we're running the test on a 32-bit box, of course.
32
33 def to_little_endian_string(value, nbytes):
34 bytes = []
35 for i in range(nbytes):
36 bytes.append(chr(value & 0xff))
37 value >>= 8
38 return ''.join(bytes)
39
40 maxint64 = (1L << 63) - 1
41 minint64 = -maxint64-1
42
43 for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
44 while base:
45 s = 'I' + to_little_endian_string(base, 8)
46 got = marshal.loads(s)
47 self.assertEqual(base, got)
48 if base == -1: # a fixed-point for shifting right 1
49 base = 0
50 else:
51 base >>= 1
52
53 def test_bool(self):
54 for b in (True, False):
55 new = marshal.loads(marshal.dumps(b))
56 self.assertEqual(b, new)
57 self.assertEqual(type(b), type(new))
58 marshal.dump(b, file(test_support.TESTFN, "wb"))
59 new = marshal.load(file(test_support.TESTFN, "rb"))
60 self.assertEqual(b, new)
61 self.assertEqual(type(b), type(new))
Tim Peters58eb11c2004-01-18 20:29:55 +000062
Skip Montanaroc1b41542003-08-02 15:02:33 +000063class FloatTestCase(unittest.TestCase):
64 def test_floats(self):
65 # Test a few floats
66 small = 1e-25
67 n = sys.maxint * 3.7e250
68 while n > small:
69 for expected in (-n, n):
70 f = float(expected)
71 s = marshal.dumps(f)
72 got = marshal.loads(s)
73 self.assertEqual(f, got)
74 marshal.dump(f, file(test_support.TESTFN, "wb"))
75 got = marshal.load(file(test_support.TESTFN, "rb"))
76 self.assertEqual(f, got)
77 n /= 123.4567
78
79 f = 0.0
Michael W. Hudsondf888462005-06-03 14:41:55 +000080 s = marshal.dumps(f, 2)
Tim Peters82112372001-08-29 02:28:42 +000081 got = marshal.loads(s)
Skip Montanaroc1b41542003-08-02 15:02:33 +000082 self.assertEqual(f, got)
Michael W. Hudsondf888462005-06-03 14:41:55 +000083 # and with version <= 1 (floats marshalled differently then)
84 s = marshal.dumps(f, 1)
Tim Peters5d36a552005-06-03 22:40:27 +000085 got = marshal.loads(s)
86 self.assertEqual(f, got)
Tim Peters82112372001-08-29 02:28:42 +000087
Skip Montanaroc1b41542003-08-02 15:02:33 +000088 n = sys.maxint * 3.7e-250
89 while n < small:
90 for expected in (-n, n):
91 f = float(expected)
Tim Peters5d36a552005-06-03 22:40:27 +000092
Skip Montanaroc1b41542003-08-02 15:02:33 +000093 s = marshal.dumps(f)
94 got = marshal.loads(s)
95 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +000096
Michael W. Hudsondf888462005-06-03 14:41:55 +000097 s = marshal.dumps(f, 1)
98 got = marshal.loads(s)
99 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +0000100
Skip Montanaroc1b41542003-08-02 15:02:33 +0000101 marshal.dump(f, file(test_support.TESTFN, "wb"))
102 got = marshal.load(file(test_support.TESTFN, "rb"))
103 self.assertEqual(f, got)
Tim Peters5d36a552005-06-03 22:40:27 +0000104
Michael W. Hudsondf888462005-06-03 14:41:55 +0000105 marshal.dump(f, file(test_support.TESTFN, "wb"), 1)
106 got = marshal.load(file(test_support.TESTFN, "rb"))
107 self.assertEqual(f, got)
Skip Montanaroc1b41542003-08-02 15:02:33 +0000108 n *= 123.4567
109 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000110
Skip Montanaroc1b41542003-08-02 15:02:33 +0000111class StringTestCase(unittest.TestCase):
112 def test_unicode(self):
113 for s in [u"", u"Andrè Previn", u"abc", u" "*10000]:
114 new = marshal.loads(marshal.dumps(s))
115 self.assertEqual(s, new)
116 self.assertEqual(type(s), type(new))
117 marshal.dump(s, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000118 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000119 self.assertEqual(s, new)
120 self.assertEqual(type(s), type(new))
121 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000122
Skip Montanaroc1b41542003-08-02 15:02:33 +0000123 def test_string(self):
124 for s in ["", "Andrè Previn", "abc", " "*10000]:
125 new = marshal.loads(marshal.dumps(s))
126 self.assertEqual(s, new)
127 self.assertEqual(type(s), type(new))
128 marshal.dump(s, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000129 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000130 self.assertEqual(s, new)
131 self.assertEqual(type(s), type(new))
132 os.unlink(test_support.TESTFN)
Tim Peters82112372001-08-29 02:28:42 +0000133
Skip Montanaroc1b41542003-08-02 15:02:33 +0000134 def test_buffer(self):
135 for s in ["", "Andrè Previn", "abc", " "*10000]:
Florent Xicluna07627882010-03-21 01:14:24 +0000136 with test_support.check_py3k_warnings(("buffer.. not supported",
137 DeprecationWarning)):
138 b = buffer(s)
Skip Montanaroc1b41542003-08-02 15:02:33 +0000139 new = marshal.loads(marshal.dumps(b))
140 self.assertEqual(s, new)
141 marshal.dump(b, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000142 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000143 self.assertEqual(s, new)
144 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000145
Skip Montanaroc1b41542003-08-02 15:02:33 +0000146class ExceptionTestCase(unittest.TestCase):
147 def test_exceptions(self):
148 new = marshal.loads(marshal.dumps(StopIteration))
149 self.assertEqual(StopIteration, new)
Thomas Heller3e1c18a2002-07-30 11:40:57 +0000150
Skip Montanaroc1b41542003-08-02 15:02:33 +0000151class CodeTestCase(unittest.TestCase):
152 def test_code(self):
153 co = ExceptionTestCase.test_exceptions.func_code
154 new = marshal.loads(marshal.dumps(co))
155 self.assertEqual(co, new)
156
157class ContainerTestCase(unittest.TestCase):
158 d = {'astring': 'foo@bar.baz.spam',
159 'afloat': 7283.43,
160 'anint': 2**20,
161 'ashortlong': 2L,
162 'alist': ['.zyx.41'],
163 'atuple': ('.zyx.41',)*10,
164 'aboolean': False,
165 'aunicode': u"Andrè Previn"
166 }
167 def test_dict(self):
168 new = marshal.loads(marshal.dumps(self.d))
169 self.assertEqual(self.d, new)
170 marshal.dump(self.d, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000171 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000172 self.assertEqual(self.d, new)
173 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000174
Skip Montanaroc1b41542003-08-02 15:02:33 +0000175 def test_list(self):
176 lst = self.d.items()
177 new = marshal.loads(marshal.dumps(lst))
178 self.assertEqual(lst, new)
179 marshal.dump(lst, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000180 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000181 self.assertEqual(lst, new)
182 os.unlink(test_support.TESTFN)
183
184 def test_tuple(self):
185 t = tuple(self.d.keys())
186 new = marshal.loads(marshal.dumps(t))
187 self.assertEqual(t, new)
188 marshal.dump(t, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000189 new = marshal.load(file(test_support.TESTFN, "rb"))
Skip Montanaroc1b41542003-08-02 15:02:33 +0000190 self.assertEqual(t, new)
191 os.unlink(test_support.TESTFN)
Tim Peters58eb11c2004-01-18 20:29:55 +0000192
Raymond Hettingera422c342005-01-11 03:03:27 +0000193 def test_sets(self):
194 for constructor in (set, frozenset):
195 t = constructor(self.d.keys())
196 new = marshal.loads(marshal.dumps(t))
197 self.assertEqual(t, new)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000198 self.assertTrue(isinstance(new, constructor))
Raymond Hettingera422c342005-01-11 03:03:27 +0000199 self.assertNotEqual(id(t), id(new))
200 marshal.dump(t, file(test_support.TESTFN, "wb"))
Skip Montanaro61aa6302005-06-04 12:55:32 +0000201 new = marshal.load(file(test_support.TESTFN, "rb"))
Raymond Hettingera422c342005-01-11 03:03:27 +0000202 self.assertEqual(t, new)
203 os.unlink(test_support.TESTFN)
204
Skip Montanaroc1b41542003-08-02 15:02:33 +0000205class BugsTestCase(unittest.TestCase):
206 def test_bug_5888452(self):
207 # Simple-minded check for SF 588452: Debug build crashes
208 marshal.dumps([128] * 1000)
209
Armin Rigo01ab2792004-03-26 15:09:27 +0000210 def test_patch_873224(self):
211 self.assertRaises(Exception, marshal.loads, '0')
212 self.assertRaises(Exception, marshal.loads, 'f')
213 self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1])
214
Armin Rigo2ccea172004-12-20 12:25:57 +0000215 def test_version_argument(self):
216 # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
Ezio Melotti2623a372010-11-21 13:34:58 +0000217 self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5)
218 self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5)
Armin Rigo2ccea172004-12-20 12:25:57 +0000219
Michael W. Hudsonf2ca5af2005-06-13 18:28:46 +0000220 def test_fuzz(self):
221 # simple test that it's at least not *totally* trivial to
222 # crash from bad marshal data
223 for c in [chr(i) for i in range(256)]:
224 try:
225 marshal.loads(c)
226 except Exception:
227 pass
228
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000229 def test_loads_recursion(self):
Serhiy Storchaka9720f602018-07-05 12:20:19 +0300230 def run_tests(N, check):
231 # (((...None...),),)
232 check(b'(\x01\x00\x00\x00' * N + b'N')
233 # [[[...None...]]]
234 check(b'[\x01\x00\x00\x00' * N + b'N')
235 # {None: {None: {None: ...None...}}}
236 check(b'{N' * N + b'N' + b'0' * N)
237 # frozenset([frozenset([frozenset([...None...])])])
238 check(b'>\x01\x00\x00\x00' * N + b'N')
239 # Check that the generated marshal data is valid and marshal.loads()
240 # works for moderately deep nesting
241 run_tests(100, marshal.loads)
242 # Very deeply nested structure shouldn't blow the stack
243 def check(s):
244 self.assertRaises(ValueError, marshal.loads, s)
245 run_tests(2**20, check)
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000246
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000247 def test_recursion_limit(self):
248 # Create a deeply nested structure.
249 head = last = []
250 # The max stack depth should match the value in Python/marshal.c.
Benjamin Peterson64c82752016-07-06 23:37:02 -0700251 if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'):
252 MAX_MARSHAL_STACK_DEPTH = 1000
253 else:
254 MAX_MARSHAL_STACK_DEPTH = 2000
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000255 for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
256 last.append([0])
257 last = last[-1]
258
259 # Verify we don't blow out the stack with dumps/load.
260 data = marshal.dumps(head)
261 new_head = marshal.loads(data)
262 # Don't use == to compare objects, it can exceed the recursion limit.
263 self.assertEqual(len(new_head), len(head))
264 self.assertEqual(len(new_head[0]), len(head[0]))
265 self.assertEqual(len(new_head[-1]), len(head[-1]))
266
267 last.append([0])
268 self.assertRaises(ValueError, marshal.dumps, head)
269
Raymond Hettinger12e94202007-11-07 01:13:09 +0000270 def test_exact_type_match(self):
271 # Former bug:
272 # >>> class Int(int): pass
273 # >>> type(loads(dumps(Int())))
274 # <type 'int'>
275 for typ in (int, long, float, complex, tuple, list, dict, set, frozenset):
Ezio Melottic2077b02011-03-16 12:34:31 +0200276 # Note: str and unicode subclasses are not tested because they get handled
Raymond Hettinger12e94202007-11-07 01:13:09 +0000277 # by marshal's routines for objects supporting the buffer API.
278 subtyp = type('subtyp', (typ,), {})
279 self.assertRaises(ValueError, marshal.dumps, subtyp())
280
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000281 # Issue #1792 introduced a change in how marshal increases the size of its
282 # internal buffer; this test ensures that the new code is exercised.
283 def test_large_marshal(self):
284 size = int(1e6)
285 testString = 'abc' * size
286 marshal.dumps(testString)
287
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000288 def test_invalid_longs(self):
289 # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
290 invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00'
291 self.assertRaises(ValueError, marshal.loads, invalid_string)
292
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200293LARGE_SIZE = 2**31
294character_size = 4 if sys.maxunicode > 0xFFFF else 2
295pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
296
297@unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems")
298class LargeValuesTestCase(unittest.TestCase):
299 def check_unmarshallable(self, data):
300 f = open(test_support.TESTFN, 'wb')
301 self.addCleanup(test_support.unlink, test_support.TESTFN)
302 with f:
303 self.assertRaises(ValueError, marshal.dump, data, f)
304
305 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200306 def test_string(self, size):
307 self.check_unmarshallable('x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200308
309 @test_support.precisionbigmemtest(size=LARGE_SIZE,
Serhiy Storchakac9da0892014-01-10 13:36:56 +0200310 memuse=character_size + 2, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200311 def test_unicode(self, size):
312 self.check_unmarshallable(u'x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200313
314 @test_support.precisionbigmemtest(size=LARGE_SIZE,
315 memuse=pointer_size, dry_run=False)
316 def test_tuple(self, size):
317 self.check_unmarshallable((None,) * size)
318
319 @test_support.precisionbigmemtest(size=LARGE_SIZE,
320 memuse=pointer_size, dry_run=False)
321 def test_list(self, size):
322 self.check_unmarshallable([None] * size)
323
324 @test_support.precisionbigmemtest(size=LARGE_SIZE,
325 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
326 dry_run=False)
327 def test_set(self, size):
328 self.check_unmarshallable(set(range(size)))
329
330 @test_support.precisionbigmemtest(size=LARGE_SIZE,
331 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
332 dry_run=False)
333 def test_frozenset(self, size):
334 self.check_unmarshallable(frozenset(range(size)))
335
336 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
337 def test_bytearray(self, size):
338 self.check_unmarshallable(bytearray(size))
339
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000340
Serhiy Storchaka4068b012015-02-06 08:56:33 +0200341@test_support.cpython_only
342@unittest.skipUnless(_testcapi, 'requires _testcapi')
343class CAPI_TestCase(unittest.TestCase):
344
345 def test_write_long_to_file(self):
346 for v in range(marshal.version + 1):
347 _testcapi.pymarshal_write_long_to_file(0x12345678, test_support.TESTFN, v)
348 with open(test_support.TESTFN, 'rb') as f:
349 data = f.read()
350 test_support.unlink(test_support.TESTFN)
351 self.assertEqual(data, b'\x78\x56\x34\x12')
352
353 def test_write_object_to_file(self):
354 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j, 'long line '*1000)
355 for v in range(marshal.version + 1):
356 _testcapi.pymarshal_write_object_to_file(obj, test_support.TESTFN, v)
357 with open(test_support.TESTFN, 'rb') as f:
358 data = f.read()
359 test_support.unlink(test_support.TESTFN)
360 self.assertEqual(marshal.loads(data), obj)
361
362 def test_read_short_from_file(self):
363 with open(test_support.TESTFN, 'wb') as f:
364 f.write(b'\x34\x12xxxx')
365 r, p = _testcapi.pymarshal_read_short_from_file(test_support.TESTFN)
366 test_support.unlink(test_support.TESTFN)
367 self.assertEqual(r, 0x1234)
368 self.assertEqual(p, 2)
369
370 def test_read_long_from_file(self):
371 with open(test_support.TESTFN, 'wb') as f:
372 f.write(b'\x78\x56\x34\x12xxxx')
373 r, p = _testcapi.pymarshal_read_long_from_file(test_support.TESTFN)
374 test_support.unlink(test_support.TESTFN)
375 self.assertEqual(r, 0x12345678)
376 self.assertEqual(p, 4)
377
378 def test_read_last_object_from_file(self):
379 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
380 for v in range(marshal.version + 1):
381 data = marshal.dumps(obj, v)
382 with open(test_support.TESTFN, 'wb') as f:
383 f.write(data + b'xxxx')
384 r, p = _testcapi.pymarshal_read_last_object_from_file(test_support.TESTFN)
385 test_support.unlink(test_support.TESTFN)
386 self.assertEqual(r, obj)
387
388 def test_read_object_from_file(self):
389 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
390 for v in range(marshal.version + 1):
391 data = marshal.dumps(obj, v)
392 with open(test_support.TESTFN, 'wb') as f:
393 f.write(data + b'xxxx')
394 r, p = _testcapi.pymarshal_read_object_from_file(test_support.TESTFN)
395 test_support.unlink(test_support.TESTFN)
396 self.assertEqual(r, obj)
397 self.assertEqual(p, len(data))
398
399
Skip Montanaroc1b41542003-08-02 15:02:33 +0000400def test_main():
401 test_support.run_unittest(IntTestCase,
402 FloatTestCase,
403 StringTestCase,
404 CodeTestCase,
405 ContainerTestCase,
406 ExceptionTestCase,
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200407 BugsTestCase,
408 LargeValuesTestCase,
Serhiy Storchaka4068b012015-02-06 08:56:33 +0200409 CAPI_TestCase,
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200410 )
Skip Montanaroc1b41542003-08-02 15:02:33 +0000411
412if __name__ == "__main__":
413 test_main()