diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst index ff82b685..18697d42 100644 --- a/docs/versionhistory.rst +++ b/docs/versionhistory.rst @@ -5,6 +5,10 @@ Version history This library adheres to `Semantic Versioning `_. +**UNRELEASED** + +- Fixed ``SystemError`` when decoding a ``Fractional`` with a bad number of arguments + **5.5.1** (2023-11-02) - Fixed ``CBORSimpleValue`` allowing the use of reserved values (24 to 31) which resulted in diff --git a/source/decoder.c b/source/decoder.c index 81aa090a..35f817c6 100644 --- a/source/decoder.c +++ b/source/decoder.c @@ -1367,16 +1367,14 @@ CBORDecoder_decode_rational(CBORDecoderObject *self) // NOTE: see semantic type 4 tuple = decode(self, DECODE_IMMUTABLE | DECODE_UNSHARED); if (tuple) { - if (PyTuple_CheckExact(tuple) && PyTuple_GET_SIZE(tuple) == 2) { - ret = PyObject_CallFunctionObjArgs( - _CBOR2_Fraction, - PyTuple_GET_ITEM(tuple, 0), - PyTuple_GET_ITEM(tuple, 1), - NULL); + if (PyTuple_CheckExact(tuple)) { + ret = PyObject_Call(_CBOR2_Fraction, tuple, NULL); + if (ret) { + set_shareable(self, ret); + } } Py_DECREF(tuple); } - set_shareable(self, ret); return ret; } diff --git a/tests/test_decoder.py b/tests/test_decoder.py index 1c5e0213..ab0b8484 100644 --- a/tests/test_decoder.py +++ b/tests/test_decoder.py @@ -809,3 +809,18 @@ def test_decimal_payload_unpacking(impl, data, expected): with pytest.raises(impl.CBORDecodeValueError) as exc_info: impl.loads(unhexlify(data)) assert exc_info.value.args[0] == f"Incorrect tag {expected} payload" + + +@pytest.mark.parametrize( + "payload, exception, pattern", + [ + pytest.param( + b"\xd8\x1e\x84\xff\xff\xff\xff", + TypeError, + r"__new__\(\) takes from 1 to 3 positional arguments but 5 were given", + ) + ], +) +def test_invalid_data(impl, payload, exception, pattern) -> None: + with pytest.raises(exception, match=pattern): + impl.loads(b"\xd8\x1e\x84\xff\xff\xff\xff")