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

Original file line numberDiff line numberDiff line change

@@ -210,13 +210,24 @@ def test_fuzz(self):

210210

except Exception:

211211

pass

212212
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-
217213

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)

220231
221232

def test_recursion_limit(self):

222233

# Create a deeply nested structure.