blob: 1967c4807ea3c71276a15d0612196c2d025451a1 [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):
Neal Norwitzb1a9b372007-05-16 20:05:11 +0000230 s = 'c' + ('X' * 4*4) + '{' * 2**20
231 self.assertRaises(ValueError, marshal.loads, s)
232
Neal Norwitz6eb7bed2007-05-18 05:47:16 +0000233 def test_recursion_limit(self):
234 # Create a deeply nested structure.
235 head = last = []
236 # The max stack depth should match the value in Python/marshal.c.
237 MAX_MARSHAL_STACK_DEPTH = 2000
238 for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
239 last.append([0])
240 last = last[-1]
241
242 # Verify we don't blow out the stack with dumps/load.
243 data = marshal.dumps(head)
244 new_head = marshal.loads(data)
245 # Don't use == to compare objects, it can exceed the recursion limit.
246 self.assertEqual(len(new_head), len(head))
247 self.assertEqual(len(new_head[0]), len(head[0]))
248 self.assertEqual(len(new_head[-1]), len(head[-1]))
249
250 last.append([0])
251 self.assertRaises(ValueError, marshal.dumps, head)
252
Raymond Hettinger12e94202007-11-07 01:13:09 +0000253 def test_exact_type_match(self):
254 # Former bug:
255 # >>> class Int(int): pass
256 # >>> type(loads(dumps(Int())))
257 # <type 'int'>
258 for typ in (int, long, float, complex, tuple, list, dict, set, frozenset):
Ezio Melottic2077b02011-03-16 12:34:31 +0200259 # Note: str and unicode subclasses are not tested because they get handled
Raymond Hettinger12e94202007-11-07 01:13:09 +0000260 # by marshal's routines for objects supporting the buffer API.
261 subtyp = type('subtyp', (typ,), {})
262 self.assertRaises(ValueError, marshal.dumps, subtyp())
263
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000264 # Issue #1792 introduced a change in how marshal increases the size of its
265 # internal buffer; this test ensures that the new code is exercised.
266 def test_large_marshal(self):
267 size = int(1e6)
268 testString = 'abc' * size
269 marshal.dumps(testString)
270
Mark Dickinson7e7a3ec2009-09-29 19:01:06 +0000271 def test_invalid_longs(self):
272 # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
273 invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00'
274 self.assertRaises(ValueError, marshal.loads, invalid_string)
275
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200276LARGE_SIZE = 2**31
277character_size = 4 if sys.maxunicode > 0xFFFF else 2
278pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
279
280@unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems")
281class LargeValuesTestCase(unittest.TestCase):
282 def check_unmarshallable(self, data):
283 f = open(test_support.TESTFN, 'wb')
284 self.addCleanup(test_support.unlink, test_support.TESTFN)
285 with f:
286 self.assertRaises(ValueError, marshal.dump, data, f)
287
288 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200289 def test_string(self, size):
290 self.check_unmarshallable('x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200291
292 @test_support.precisionbigmemtest(size=LARGE_SIZE,
Serhiy Storchakac9da0892014-01-10 13:36:56 +0200293 memuse=character_size + 2, dry_run=False)
Serhiy Storchakaec50cb22013-02-13 12:31:19 +0200294 def test_unicode(self, size):
295 self.check_unmarshallable(u'x' * size)
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200296
297 @test_support.precisionbigmemtest(size=LARGE_SIZE,
298 memuse=pointer_size, dry_run=False)
299 def test_tuple(self, size):
300 self.check_unmarshallable((None,) * size)
301
302 @test_support.precisionbigmemtest(size=LARGE_SIZE,
303 memuse=pointer_size, dry_run=False)
304 def test_list(self, size):
305 self.check_unmarshallable([None] * size)
306
307 @test_support.precisionbigmemtest(size=LARGE_SIZE,
308 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
309 dry_run=False)
310 def test_set(self, size):
311 self.check_unmarshallable(set(range(size)))
312
313 @test_support.precisionbigmemtest(size=LARGE_SIZE,
314 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
315 dry_run=False)
316 def test_frozenset(self, size):
317 self.check_unmarshallable(frozenset(range(size)))
318
319 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False)
320 def test_bytearray(self, size):
321 self.check_unmarshallable(bytearray(size))
322
Andrew M. Kuchling6c029162008-05-11 13:33:56 +0000323
Serhiy Storchaka4068b012015-02-06 08:56:33 +0200324@test_support.cpython_only
325@unittest.skipUnless(_testcapi, 'requires _testcapi')
326class CAPI_TestCase(unittest.TestCase):
327
328 def test_write_long_to_file(self):
329 for v in range(marshal.version + 1):
330 _testcapi.pymarshal_write_long_to_file(0x12345678, test_support.TESTFN, v)
331 with open(test_support.TESTFN, 'rb') as f:
332 data = f.read()
333 test_support.unlink(test_support.TESTFN)
334 self.assertEqual(data, b'\x78\x56\x34\x12')
335
336 def test_write_object_to_file(self):
337 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j, 'long line '*1000)
338 for v in range(marshal.version + 1):
339 _testcapi.pymarshal_write_object_to_file(obj, test_support.TESTFN, v)
340 with open(test_support.TESTFN, 'rb') as f:
341 data = f.read()
342 test_support.unlink(test_support.TESTFN)
343 self.assertEqual(marshal.loads(data), obj)
344
345 def test_read_short_from_file(self):
346 with open(test_support.TESTFN, 'wb') as f:
347 f.write(b'\x34\x12xxxx')
348 r, p = _testcapi.pymarshal_read_short_from_file(test_support.TESTFN)
349 test_support.unlink(test_support.TESTFN)
350 self.assertEqual(r, 0x1234)
351 self.assertEqual(p, 2)
352
353 def test_read_long_from_file(self):
354 with open(test_support.TESTFN, 'wb') as f:
355 f.write(b'\x78\x56\x34\x12xxxx')
356 r, p = _testcapi.pymarshal_read_long_from_file(test_support.TESTFN)
357 test_support.unlink(test_support.TESTFN)
358 self.assertEqual(r, 0x12345678)
359 self.assertEqual(p, 4)
360
361 def test_read_last_object_from_file(self):
362 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
363 for v in range(marshal.version + 1):
364 data = marshal.dumps(obj, v)
365 with open(test_support.TESTFN, 'wb') as f:
366 f.write(data + b'xxxx')
367 r, p = _testcapi.pymarshal_read_last_object_from_file(test_support.TESTFN)
368 test_support.unlink(test_support.TESTFN)
369 self.assertEqual(r, obj)
370
371 def test_read_object_from_file(self):
372 obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
373 for v in range(marshal.version + 1):
374 data = marshal.dumps(obj, v)
375 with open(test_support.TESTFN, 'wb') as f:
376 f.write(data + b'xxxx')
377 r, p = _testcapi.pymarshal_read_object_from_file(test_support.TESTFN)
378 test_support.unlink(test_support.TESTFN)
379 self.assertEqual(r, obj)
380 self.assertEqual(p, len(data))
381
382
Skip Montanaroc1b41542003-08-02 15:02:33 +0000383def test_main():
384 test_support.run_unittest(IntTestCase,
385 FloatTestCase,
386 StringTestCase,
387 CodeTestCase,
388 ContainerTestCase,
389 ExceptionTestCase,
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200390 BugsTestCase,
391 LargeValuesTestCase,
Serhiy Storchaka4068b012015-02-06 08:56:33 +0200392 CAPI_TestCase,
Serhiy Storchaka34fe1b72013-02-13 12:07:43 +0200393 )
Skip Montanaroc1b41542003-08-02 15:02:33 +0000394
395if __name__ == "__main__":
396 test_main()