1 from json.tests import PyTest, CTest 2 3 4 class JSONTestObject: 5 pass 6 7 8 class TestRecursion(object): 9 def test_listrecursion(self): 10 x = [] 11 x.append(x) 12 try: 13 self.dumps(x) 14 except ValueError: 15 pass 16 else: 17 self.fail("didn't raise ValueError on list recursion") 18 x = [] 19 y = [x] 20 x.append(y) 21 try: 22 self.dumps(x) 23 except ValueError: 24 pass 25 else: 26 self.fail("didn't raise ValueError on alternating list recursion") 27 y = [] 28 x = [y, y] 29 # ensure that the marker is cleared 30 self.dumps(x) 31 32 def test_dictrecursion(self): 33 x = {} 34 x["test"] = x 35 try: 36 self.dumps(x) 37 except ValueError: 38 pass 39 else: 40 self.fail("didn't raise ValueError on dict recursion") 41 x = {} 42 y = {"a": x, "b": x} 43 # ensure that the marker is cleared 44 self.dumps(x) 45 46 def test_defaultrecursion(self): 47 class RecursiveJSONEncoder(self.json.JSONEncoder): 48 recurse = False 49 def default(self, o): 50 if o is JSONTestObject: 51 if self.recurse: 52 return [JSONTestObject] 53 else: 54 return 'JSONTestObject' 55 return pyjson.JSONEncoder.default(o) 56 57 enc = RecursiveJSONEncoder() 58 self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"') 59 enc.recurse = True 60 try: 61 enc.encode(JSONTestObject) 62 except ValueError: 63 pass 64 else: 65 self.fail("didn't raise ValueError on default recursion") 66 67 68 def test_highly_nested_objects_decoding(self): 69 # test that loading highly-nested objects doesn't segfault when C 70 # accelerations are used. See #12017 71 # str 72 with self.assertRaises(RuntimeError): 73 self.loads('{"a":' * 100000 + '1' + '}' * 100000) 74 with self.assertRaises(RuntimeError): 75 self.loads('{"a":' * 100000 + '[1]' + '}' * 100000) 76 with self.assertRaises(RuntimeError): 77 self.loads('[' * 100000 + '1' + ']' * 100000) 78 # unicode 79 with self.assertRaises(RuntimeError): 80 self.loads(u'{"a":' * 100000 + u'1' + u'}' * 100000) 81 with self.assertRaises(RuntimeError): 82 self.loads(u'{"a":' * 100000 + u'[1]' + u'}' * 100000) 83 with self.assertRaises(RuntimeError): 84 self.loads(u'[' * 100000 + u'1' + u']' * 100000) 85 86 def test_highly_nested_objects_encoding(self): 87 # See #12051 88 l, d = [], {} 89 for x in xrange(100000): 90 l, d = [l], {'k':d} 91 with self.assertRaises(RuntimeError): 92 self.dumps(l) 93 with self.assertRaises(RuntimeError): 94 self.dumps(d) 95 96 def test_endless_recursion(self): 97 # See #12051 98 class EndlessJSONEncoder(self.json.JSONEncoder): 99 def default(self, o): 100 """If check_circular is False, this will keep adding another list.""" 101 return [o] 102 103 with self.assertRaises(RuntimeError): 104 EndlessJSONEncoder(check_circular=False).encode(5j) 105 106 107 class TestPyRecursion(TestRecursion, PyTest): pass 108 class TestCRecursion(TestRecursion, CTest): pass 109