From 415599f5d0b94a9156d7c03c7209d5c42634e237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Wed, 27 Dec 2023 14:36:57 +0200 Subject: [PATCH] Fixed exceptions raised from decoder object hook causing SystemError Fixes #201. --- docs/versionhistory.rst | 5 ++++- source/decoder.c | 11 ++++++----- tests/test_decoder.py | 9 +++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst index defb976c..65b38eca 100644 --- a/docs/versionhistory.rst +++ b/docs/versionhistory.rst @@ -7,7 +7,10 @@ This library adheres to `Semantic Versioning `_. **UNRELEASED** -- Fixed ``SystemError`` when decoding a ``Fractional`` with a bad number of arguments +- Fixed ``SystemError`` in the C extension when decoding a ``Fractional`` with a bad + number of arguments +- Fixed ``SystemError`` in the C extension when the decoder object hook raises an + exception - Fixed a segmentation fault when decoding invalid unicode data **5.5.1** (2023-11-02) diff --git a/source/decoder.c b/source/decoder.c index 1ba709e4..7b53c3f5 100644 --- a/source/decoder.c +++ b/source/decoder.c @@ -939,11 +939,12 @@ decode_map(CBORDecoderObject *self, uint8_t subtype) } if (ret && self->object_hook != Py_None) { map = PyObject_CallFunctionObjArgs(self->object_hook, self, ret, NULL); - if (map) { - set_shareable(self, map); - Py_DECREF(ret); - ret = map; - } + if (!map) + return NULL; + + set_shareable(self, map); + Py_DECREF(ret); + ret = map; } return ret; } diff --git a/tests/test_decoder.py b/tests/test_decoder.py index 7ea86075..0fd79dae 100644 --- a/tests/test_decoder.py +++ b/tests/test_decoder.py @@ -690,6 +690,15 @@ def __init__(self, state): assert decoded.state == {"a": 3, "b": 5} +def test_object_hook_exception(impl): + def object_hook(decoder, data): + raise RuntimeError("foo") + + payload = unhexlify("A2616103616205") + with pytest.raises(RuntimeError, match="foo"): + impl.loads(payload, object_hook=object_hook) + + def test_load_from_file(impl, tmpdir): path = tmpdir.join("testdata.cbor") path.write_binary(b"\x82\x01\x0a")