1 #!/usr/bin/env python 2 # -*- coding: iso-8859-1 -*- 3 4 from test import test_support 5 import marshal 6 import sys 7 import unittest 8 import os 9 10 class IntTestCase(unittest.TestCase): 11 def test_ints(self): 12 # Test the full range of Python ints. 13 n = sys.maxint 14 while n: 15 for expected in (-n, n): 16 s = marshal.dumps(expected) 17 got = marshal.loads(s) 18 self.assertEqual(expected, got) 19 marshal.dump(expected, file(test_support.TESTFN, "wb")) 20 got = marshal.load(file(test_support.TESTFN, "rb")) 21 self.assertEqual(expected, got) 22 n = n >> 1 23 os.unlink(test_support.TESTFN) 24 25 def test_int64(self): 26 # Simulate int marshaling on a 64-bit box. This is most interesting if 27 # we're running the test on a 32-bit box, of course. 28 29 def to_little_endian_string(value, nbytes): 30 bytes = [] 31 for i in range(nbytes): 32 bytes.append(chr(value & 0xff)) 33 value >>= 8 34 return ''.join(bytes) 35 36 maxint64 = (1L << 63) - 1 37 minint64 = -maxint64-1 38 39 for base in maxint64, minint64, -maxint64, -(minint64 >> 1): 40 while base: 41 s = 'I' + to_little_endian_string(base, 8) 42 got = marshal.loads(s) 43 self.assertEqual(base, got) 44 if base == -1: # a fixed-point for shifting right 1 45 base = 0 46 else: 47 base >>= 1 48 49 def test_bool(self): 50 for b in (True, False): 51 new = marshal.loads(marshal.dumps(b)) 52 self.assertEqual(b, new) 53 self.assertEqual(type(b), type(new)) 54 marshal.dump(b, file(test_support.TESTFN, "wb")) 55 new = marshal.load(file(test_support.TESTFN, "rb")) 56 self.assertEqual(b, new) 57 self.assertEqual(type(b), type(new)) 58 59 class FloatTestCase(unittest.TestCase): 60 def test_floats(self): 61 # Test a few floats 62 small = 1e-25 63 n = sys.maxint * 3.7e250 64 while n > small: 65 for expected in (-n, n): 66 f = float(expected) 67 s = marshal.dumps(f) 68 got = marshal.loads(s) 69 self.assertEqual(f, got) 70 marshal.dump(f, file(test_support.TESTFN, "wb")) 71 got = marshal.load(file(test_support.TESTFN, "rb")) 72 self.assertEqual(f, got) 73 n /= 123.4567 74 75 f = 0.0 76 s = marshal.dumps(f, 2) 77 got = marshal.loads(s) 78 self.assertEqual(f, got) 79 # and with version <= 1 (floats marshalled differently then) 80 s = marshal.dumps(f, 1) 81 got = marshal.loads(s) 82 self.assertEqual(f, got) 83 84 n = sys.maxint * 3.7e-250 85 while n < small: 86 for expected in (-n, n): 87 f = float(expected) 88 89 s = marshal.dumps(f) 90 got = marshal.loads(s) 91 self.assertEqual(f, got) 92 93 s = marshal.dumps(f, 1) 94 got = marshal.loads(s) 95 self.assertEqual(f, got) 96 97 marshal.dump(f, file(test_support.TESTFN, "wb")) 98 got = marshal.load(file(test_support.TESTFN, "rb")) 99 self.assertEqual(f, got) 100 101 marshal.dump(f, file(test_support.TESTFN, "wb"), 1) 102 got = marshal.load(file(test_support.TESTFN, "rb")) 103 self.assertEqual(f, got) 104 n *= 123.4567 105 os.unlink(test_support.TESTFN) 106 107 class StringTestCase(unittest.TestCase): 108 def test_unicode(self): 109 for s in [u"", u"Andr Previn", u"abc", u" "*10000]: 110 new = marshal.loads(marshal.dumps(s)) 111 self.assertEqual(s, new) 112 self.assertEqual(type(s), type(new)) 113 marshal.dump(s, file(test_support.TESTFN, "wb")) 114 new = marshal.load(file(test_support.TESTFN, "rb")) 115 self.assertEqual(s, new) 116 self.assertEqual(type(s), type(new)) 117 os.unlink(test_support.TESTFN) 118 119 def test_string(self): 120 for s in ["", "Andr Previn", "abc", " "*10000]: 121 new = marshal.loads(marshal.dumps(s)) 122 self.assertEqual(s, new) 123 self.assertEqual(type(s), type(new)) 124 marshal.dump(s, file(test_support.TESTFN, "wb")) 125 new = marshal.load(file(test_support.TESTFN, "rb")) 126 self.assertEqual(s, new) 127 self.assertEqual(type(s), type(new)) 128 os.unlink(test_support.TESTFN) 129 130 def test_buffer(self): 131 for s in ["", "Andr Previn", "abc", " "*10000]: 132 with test_support.check_py3k_warnings(("buffer.. not supported", 133 DeprecationWarning)): 134 b = buffer(s) 135 new = marshal.loads(marshal.dumps(b)) 136 self.assertEqual(s, new) 137 marshal.dump(b, file(test_support.TESTFN, "wb")) 138 new = marshal.load(file(test_support.TESTFN, "rb")) 139 self.assertEqual(s, new) 140 os.unlink(test_support.TESTFN) 141 142 class ExceptionTestCase(unittest.TestCase): 143 def test_exceptions(self): 144 new = marshal.loads(marshal.dumps(StopIteration)) 145 self.assertEqual(StopIteration, new) 146 147 class CodeTestCase(unittest.TestCase): 148 def test_code(self): 149 co = ExceptionTestCase.test_exceptions.func_code 150 new = marshal.loads(marshal.dumps(co)) 151 self.assertEqual(co, new) 152 153 class ContainerTestCase(unittest.TestCase): 154 d = {'astring': 'foo (at] bar.baz.spam', 155 'afloat': 7283.43, 156 'anint': 2**20, 157 'ashortlong': 2L, 158 'alist': ['.zyx.41'], 159 'atuple': ('.zyx.41',)*10, 160 'aboolean': False, 161 'aunicode': u"Andr Previn" 162 } 163 def test_dict(self): 164 new = marshal.loads(marshal.dumps(self.d)) 165 self.assertEqual(self.d, new) 166 marshal.dump(self.d, file(test_support.TESTFN, "wb")) 167 new = marshal.load(file(test_support.TESTFN, "rb")) 168 self.assertEqual(self.d, new) 169 os.unlink(test_support.TESTFN) 170 171 def test_list(self): 172 lst = self.d.items() 173 new = marshal.loads(marshal.dumps(lst)) 174 self.assertEqual(lst, new) 175 marshal.dump(lst, file(test_support.TESTFN, "wb")) 176 new = marshal.load(file(test_support.TESTFN, "rb")) 177 self.assertEqual(lst, new) 178 os.unlink(test_support.TESTFN) 179 180 def test_tuple(self): 181 t = tuple(self.d.keys()) 182 new = marshal.loads(marshal.dumps(t)) 183 self.assertEqual(t, new) 184 marshal.dump(t, file(test_support.TESTFN, "wb")) 185 new = marshal.load(file(test_support.TESTFN, "rb")) 186 self.assertEqual(t, new) 187 os.unlink(test_support.TESTFN) 188 189 def test_sets(self): 190 for constructor in (set, frozenset): 191 t = constructor(self.d.keys()) 192 new = marshal.loads(marshal.dumps(t)) 193 self.assertEqual(t, new) 194 self.assertTrue(isinstance(new, constructor)) 195 self.assertNotEqual(id(t), id(new)) 196 marshal.dump(t, file(test_support.TESTFN, "wb")) 197 new = marshal.load(file(test_support.TESTFN, "rb")) 198 self.assertEqual(t, new) 199 os.unlink(test_support.TESTFN) 200 201 class BugsTestCase(unittest.TestCase): 202 def test_bug_5888452(self): 203 # Simple-minded check for SF 588452: Debug build crashes 204 marshal.dumps([128] * 1000) 205 206 def test_patch_873224(self): 207 self.assertRaises(Exception, marshal.loads, '0') 208 self.assertRaises(Exception, marshal.loads, 'f') 209 self.assertRaises(Exception, marshal.loads, marshal.dumps(5L)[:-1]) 210 211 def test_version_argument(self): 212 # Python 2.4.0 crashes for any call to marshal.dumps(x, y) 213 self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5) 214 self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5) 215 216 def test_fuzz(self): 217 # simple test that it's at least not *totally* trivial to 218 # crash from bad marshal data 219 for c in [chr(i) for i in range(256)]: 220 try: 221 marshal.loads(c) 222 except Exception: 223 pass 224 225 def test_loads_recursion(self): 226 s = 'c' + ('X' * 4*4) + '{' * 2**20 227 self.assertRaises(ValueError, marshal.loads, s) 228 229 def test_recursion_limit(self): 230 # Create a deeply nested structure. 231 head = last = [] 232 # The max stack depth should match the value in Python/marshal.c. 233 MAX_MARSHAL_STACK_DEPTH = 2000 234 for i in range(MAX_MARSHAL_STACK_DEPTH - 2): 235 last.append([0]) 236 last = last[-1] 237 238 # Verify we don't blow out the stack with dumps/load. 239 data = marshal.dumps(head) 240 new_head = marshal.loads(data) 241 # Don't use == to compare objects, it can exceed the recursion limit. 242 self.assertEqual(len(new_head), len(head)) 243 self.assertEqual(len(new_head[0]), len(head[0])) 244 self.assertEqual(len(new_head[-1]), len(head[-1])) 245 246 last.append([0]) 247 self.assertRaises(ValueError, marshal.dumps, head) 248 249 def test_exact_type_match(self): 250 # Former bug: 251 # >>> class Int(int): pass 252 # >>> type(loads(dumps(Int()))) 253 # <type 'int'> 254 for typ in (int, long, float, complex, tuple, list, dict, set, frozenset): 255 # Note: str and unicode subclasses are not tested because they get handled 256 # by marshal's routines for objects supporting the buffer API. 257 subtyp = type('subtyp', (typ,), {}) 258 self.assertRaises(ValueError, marshal.dumps, subtyp()) 259 260 # Issue #1792 introduced a change in how marshal increases the size of its 261 # internal buffer; this test ensures that the new code is exercised. 262 def test_large_marshal(self): 263 size = int(1e6) 264 testString = 'abc' * size 265 marshal.dumps(testString) 266 267 def test_invalid_longs(self): 268 # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs 269 invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00' 270 self.assertRaises(ValueError, marshal.loads, invalid_string) 271 272 LARGE_SIZE = 2**31 273 character_size = 4 if sys.maxunicode > 0xFFFF else 2 274 pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4 275 276 @unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems") 277 class LargeValuesTestCase(unittest.TestCase): 278 def check_unmarshallable(self, data): 279 f = open(test_support.TESTFN, 'wb') 280 self.addCleanup(test_support.unlink, test_support.TESTFN) 281 with f: 282 self.assertRaises(ValueError, marshal.dump, data, f) 283 284 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False) 285 def test_string(self, size): 286 self.check_unmarshallable('x' * size) 287 288 @test_support.precisionbigmemtest(size=LARGE_SIZE, 289 memuse=character_size, dry_run=False) 290 def test_unicode(self, size): 291 self.check_unmarshallable(u'x' * size) 292 293 @test_support.precisionbigmemtest(size=LARGE_SIZE, 294 memuse=pointer_size, dry_run=False) 295 def test_tuple(self, size): 296 self.check_unmarshallable((None,) * size) 297 298 @test_support.precisionbigmemtest(size=LARGE_SIZE, 299 memuse=pointer_size, dry_run=False) 300 def test_list(self, size): 301 self.check_unmarshallable([None] * size) 302 303 @test_support.precisionbigmemtest(size=LARGE_SIZE, 304 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1), 305 dry_run=False) 306 def test_set(self, size): 307 self.check_unmarshallable(set(range(size))) 308 309 @test_support.precisionbigmemtest(size=LARGE_SIZE, 310 memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1), 311 dry_run=False) 312 def test_frozenset(self, size): 313 self.check_unmarshallable(frozenset(range(size))) 314 315 @test_support.precisionbigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False) 316 def test_bytearray(self, size): 317 self.check_unmarshallable(bytearray(size)) 318 319 320 def test_main(): 321 test_support.run_unittest(IntTestCase, 322 FloatTestCase, 323 StringTestCase, 324 CodeTestCase, 325 ContainerTestCase, 326 ExceptionTestCase, 327 BugsTestCase, 328 LargeValuesTestCase, 329 ) 330 331 if __name__ == "__main__": 332 test_main() 333