Skip to content

Commit cf0fab2

Browse files
committed
Verify neither dumps or loads overflow the stack and segfault.
1 parent ce15dce commit cf0fab2

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

Lib/test/test_marshal.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,30 @@ def test_fuzz(self):
220220
except Exception:
221221
pass
222222

223-
def test_recursion(self):
223+
def test_loads_recursion(self):
224224
s = 'c' + ('X' * 4*4) + '{' * 2**20
225225
self.assertRaises(ValueError, marshal.loads, s)
226226

227+
def test_recursion_limit(self):
228+
# Create a deeply nested structure.
229+
head = last = []
230+
# The max stack depth should match the value in Python/marshal.c.
231+
MAX_MARSHAL_STACK_DEPTH = 2000
232+
for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
233+
last.append([0])
234+
last = last[-1]
235+
236+
# Verify we don't blow out the stack with dumps/load.
237+
data = marshal.dumps(head)
238+
new_head = marshal.loads(data)
239+
# Don't use == to compare objects, it can exceed the recursion limit.
240+
self.assertEqual(len(new_head), len(head))
241+
self.assertEqual(len(new_head[0]), len(head[0]))
242+
self.assertEqual(len(new_head[-1]), len(head[-1]))
243+
244+
last.append([0])
245+
self.assertRaises(ValueError, marshal.dumps, head)
246+
227247
def test_main():
228248
test_support.run_unittest(IntTestCase,
229249
FloatTestCase,

0 commit comments

Comments
 (0)