From 9f9bdae0773166e8ed50dfdd1ed13cc4296819ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=C3=AFm=20Dimer?= <94395445+hdimer@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:48:27 -0700 Subject: [PATCH 1/2] Convert Packer's buf_size once (#726) Fixes #723. --- msgpack/_packer.pyx | 2 +- test/test_pack.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index 277239d8..e816c814 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -110,7 +110,7 @@ cdef class Packer: cdef bint autoreset cdef bint datetime - def __cinit__(self, buf_size=256*1024, **_kwargs): + def __cinit__(self, size_t buf_size=256*1024, **_kwargs): self.pk.buf = PyMem_Malloc(buf_size) if self.pk.buf == NULL: raise MemoryError("Unable to allocate internal buffer.") diff --git a/test/test_pack.py b/test/test_pack.py index 374d1549..f44bd557 100644 --- a/test/test_pack.py +++ b/test/test_pack.py @@ -179,3 +179,24 @@ def test_get_buffer(): expected = packb([1, 2], use_bin_type=True) assert written == expected + + +@pytest.mark.skipif( + Packer.__module__ == "msgpack.fallback", + reason="buf_size only allocates in the C extension", +) +def test_buf_size_is_converted_once(): + # Asking twice let the allocation and the recorded capacity disagree, + # so the packer overflowed a buffer smaller than the size it recorded. + class Counting: + count = 0 + + def __int__(self): + self.count += 1 + return 600 + + __index__ = __int__ + + buf_size = Counting() + Packer(buf_size=buf_size) + assert buf_size.count == 1 From 2e4be090f6a42e1ad19526ca6f6ee67f3476389a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=C3=AFm=20Dimer?= <94395445+hdimer@users.noreply.github.com> Date: Sun, 16 Aug 2026 22:59:09 -0700 Subject: [PATCH 2/2] fix: translate RecursionError to StackError in fallback Unpacker.skip() (#727) Finding #6 of #683. --- 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."""