From 5ab5ea2899001240f8e65573ddec64f02b64fa07 Mon Sep 17 00:00:00 2001 From: Haim Dimer Date: Sun, 16 Aug 2026 16:12:38 -0700 Subject: [PATCH] fix: translate RecursionError to StackError in fallback Unpacker.skip() skip() was the only unpack entry point in fallback.py that let a RecursionError escape on deeply nested input; unpack() and __next__() both re-raise it as StackError, and the C extension raises StackError on this path too. Callers guarding against adversarial nesting with except StackError/ValueError were unprotected when skipping. Wrap the body the same way unpack() does, leaving _consume() outside the try so the post-failure buffer state matches. --- msgpack/fallback.py | 5 ++++- test/test_except.py | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/msgpack/fallback.py b/msgpack/fallback.py index 824f59d5..e219786e 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -582,7 +582,10 @@ def __next__(self): next = __next__ def skip(self): - self._unpack(EX_SKIP) + try: + self._unpack(EX_SKIP) + except RecursionError: + raise StackError self._consume() def unpack(self): diff --git a/test/test_except.py b/test/test_except.py index a3bf4675..1e9c0045 100644 --- a/test/test_except.py +++ b/test/test_except.py @@ -97,6 +97,11 @@ def test_invalidvalue(): with raises(StackError): unpackb(b"\x91" * 3000) # nested fixarray(len=1) + with raises(StackError): + unpacker = Unpacker() + unpacker.feed(b"\x91" * 3000) + unpacker.skip() + def test_no_memory_leak_on_nested_invalid_tag() -> None: """Regression test: unpacking nested arrays containing an invalid tag must not leak objects."""