--- /dev/null
+from json.tests import PyTest, CTest\r
+\r
+\r
+class JSONTestObject:\r
+ pass\r
+\r
+\r
+class TestRecursion(object):\r
+ def test_listrecursion(self):\r
+ x = []\r
+ x.append(x)\r
+ try:\r
+ self.dumps(x)\r
+ except ValueError:\r
+ pass\r
+ else:\r
+ self.fail("didn't raise ValueError on list recursion")\r
+ x = []\r
+ y = [x]\r
+ x.append(y)\r
+ try:\r
+ self.dumps(x)\r
+ except ValueError:\r
+ pass\r
+ else:\r
+ self.fail("didn't raise ValueError on alternating list recursion")\r
+ y = []\r
+ x = [y, y]\r
+ # ensure that the marker is cleared\r
+ self.dumps(x)\r
+\r
+ def test_dictrecursion(self):\r
+ x = {}\r
+ x["test"] = x\r
+ try:\r
+ self.dumps(x)\r
+ except ValueError:\r
+ pass\r
+ else:\r
+ self.fail("didn't raise ValueError on dict recursion")\r
+ x = {}\r
+ y = {"a": x, "b": x}\r
+ # ensure that the marker is cleared\r
+ self.dumps(x)\r
+\r
+ def test_defaultrecursion(self):\r
+ class RecursiveJSONEncoder(self.json.JSONEncoder):\r
+ recurse = False\r
+ def default(self, o):\r
+ if o is JSONTestObject:\r
+ if self.recurse:\r
+ return [JSONTestObject]\r
+ else:\r
+ return 'JSONTestObject'\r
+ return pyjson.JSONEncoder.default(o)\r
+\r
+ enc = RecursiveJSONEncoder()\r
+ self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"')\r
+ enc.recurse = True\r
+ try:\r
+ enc.encode(JSONTestObject)\r
+ except ValueError:\r
+ pass\r
+ else:\r
+ self.fail("didn't raise ValueError on default recursion")\r
+\r
+\r
+ def test_highly_nested_objects_decoding(self):\r
+ # test that loading highly-nested objects doesn't segfault when C\r
+ # accelerations are used. See #12017\r
+ # str\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads('{"a":' * 100000 + '1' + '}' * 100000)\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads('{"a":' * 100000 + '[1]' + '}' * 100000)\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads('[' * 100000 + '1' + ']' * 100000)\r
+ # unicode\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads(u'{"a":' * 100000 + u'1' + u'}' * 100000)\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads(u'{"a":' * 100000 + u'[1]' + u'}' * 100000)\r
+ with self.assertRaises(RuntimeError):\r
+ self.loads(u'[' * 100000 + u'1' + u']' * 100000)\r
+\r
+ def test_highly_nested_objects_encoding(self):\r
+ # See #12051\r
+ l, d = [], {}\r
+ for x in xrange(100000):\r
+ l, d = [l], {'k':d}\r
+ with self.assertRaises(RuntimeError):\r
+ self.dumps(l)\r
+ with self.assertRaises(RuntimeError):\r
+ self.dumps(d)\r
+\r
+ def test_endless_recursion(self):\r
+ # See #12051\r
+ class EndlessJSONEncoder(self.json.JSONEncoder):\r
+ def default(self, o):\r
+ """If check_circular is False, this will keep adding another list."""\r
+ return [o]\r
+\r
+ with self.assertRaises(RuntimeError):\r
+ EndlessJSONEncoder(check_circular=False).encode(5j)\r
+\r
+\r
+class TestPyRecursion(TestRecursion, PyTest): pass\r
+class TestCRecursion(TestRecursion, CTest): pass\r