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