bpo-33720: Improve tests for the stack overflow in marshal.loads(). (… · python/cpython@fc05e68 (original) (raw)

Original file line number Diff line number Diff line change
@@ -210,13 +210,24 @@ def test_fuzz(self):
210 210 except Exception:
211 211 pass
212 212
213 -def test_loads_2x_code(self):
214 -s = b'c' + (b'X' * 4*4) + b'{' * 2**20
215 -self.assertRaises(ValueError, marshal.loads, s)
216 -
217 213 def test_loads_recursion(self):
218 -s = b'c' + (b'X' * 4*5) + b'{' * 2**20
219 -self.assertRaises(ValueError, marshal.loads, s)
214 +def run_tests(N, check):
215 +# (((...None...),),)
216 +check(b')\x01' * N + b'N')
217 +check(b'(\x01\x00\x00\x00' * N + b'N')
218 +# [[[...None...]]]
219 +check(b'[\x01\x00\x00\x00' * N + b'N')
220 +# {None: {None: {None: ...None...}}}
221 +check(b'{N' * N + b'N' + b'0' * N)
222 +# frozenset([frozenset([frozenset([...None...])])])
223 +check(b'>\x01\x00\x00\x00' * N + b'N')
224 +# Check that the generated marshal data is valid and marshal.loads()
225 +# works for moderately deep nesting
226 +run_tests(100, marshal.loads)
227 +# Very deeply nested structure shouldn't blow the stack
228 +def check(s):
229 +self.assertRaises(ValueError, marshal.loads, s)
230 +run_tests(2**20, check)
220 231
221 232 def test_recursion_limit(self):
222 233 # Create a deeply nested structure.