Home | History | Annotate | Download | only in tests
      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