Skip to content

Commit 1b54a1e

Browse files
test: add regression test
1 parent 406360b commit 1b54a1e

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

test/test_except.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python
22

33
import datetime
4+
import gc
5+
import tracemalloc
46

57
from pytest import raises
68

@@ -80,6 +82,39 @@ def test_invalidvalue():
8082
unpackb(b"\x91" * 3000) # nested fixarray(len=1)
8183

8284

85+
def test_no_memory_leak_on_nested_invalid_tag() -> None:
86+
"""Regression test: unpacking nested arrays containing an invalid tag must not leak objects."""
87+
88+
kwargs: dict = {
89+
"raw": False,
90+
"strict_map_key": False,
91+
"max_array_len": 1 << 20,
92+
"max_map_len": 1 << 20,
93+
}
94+
n = 1000
95+
96+
for depth in range(1, 15):
97+
data = bytes([0x91] * depth + [0xC1])
98+
99+
gc.collect()
100+
tracemalloc.start()
101+
s1 = tracemalloc.take_snapshot()
102+
103+
for _ in range(n):
104+
try:
105+
unpackb(data, **kwargs)
106+
except Exception:
107+
pass
108+
109+
gc.collect()
110+
s2 = tracemalloc.take_snapshot()
111+
tracemalloc.stop()
112+
113+
leaked = sum(s.count_diff for s in s2.compare_to(s1, "lineno") if s.count_diff > 0)
114+
per_call = leaked / n
115+
assert per_call < 1.0, f"depth={depth}: {per_call:.2f} leaked objects/call (expected < 1)"
116+
117+
83118
def test_strict_map_key():
84119
valid = {"unicode": 1, b"bytes": 2}
85120
packed = packb(valid, use_bin_type=True)

0 commit comments

Comments
 (0)