Skip to content

Commit

Permalink
Fixed SystemError from non-tuple input value when decoding Fraction
Browse files Browse the repository at this point in the history
  • Loading branch information
agronholm committed Jan 17, 2024
1 parent ed997ac commit b4f7fce
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
10 changes: 8 additions & 2 deletions cbor2/_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,16 @@ def decode_rational(self) -> Fraction:
# Semantic tag 30
from fractions import Fraction

inputval = self._decode(immutable=True, unshared=True)
try:
value = Fraction(*self._decode())
value = Fraction(*inputval)
except (TypeError, ZeroDivisionError) as exc:
raise CBORDecodeValueError("error decoding rational value") from exc
if not isinstance(inputval, tuple):
raise CBORDecodeValueError(
"error decoding rational: input value was not a tuple"
) from None

raise CBORDecodeValueError("error decoding rational") from exc

return self.set_shareable(value)

Expand Down
2 changes: 1 addition & 1 deletion docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This library adheres to `Semantic Versioning <http://semver.org/>`_.
- Made the C extension mandatory when the environment variable ``CBOR2_BUILD_C_EXTENSION`` is set
to ``1``.
- Fixed ``SystemError`` in the C extension when decoding a ``Fractional`` with a bad
number of arguments
number of arguments or a non-tuple value
- Fixed ``SystemError`` in the C extension when the decoder object hook raises an
exception
- Fixed a segmentation fault when decoding invalid unicode data
Expand Down
7 changes: 6 additions & 1 deletion source/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,12 @@ CBORDecoder_decode_rational(CBORDecoderObject *self)
PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError)
|| PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_ZeroDivisionError)
))
raise_from(_CBOR2_CBORDecodeValueError, "error decoding rational value");
raise_from(_CBOR2_CBORDecodeValueError, "error decoding rational");
} else {
PyErr_SetString(
_CBOR2_CBORDecodeValueError,
"error decoding rational: input value was not a tuple"
);
}
Py_DECREF(tuple);
}
Expand Down
7 changes: 7 additions & 0 deletions tests/test_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,13 @@ def test_rational(impl):
assert decoded == Fraction(2, 5)


def test_rational_invalid_iterable(impl):
with pytest.raises(
impl.CBORDecodeValueError, match="error decoding rational: input value was not a tuple"
):
impl.loads(unhexlify("d81e01"))


def test_rational_zero_denominator(impl):
with pytest.raises(impl.CBORDecodeValueError, match="error decoding rational") as exc:
impl.loads(unhexlify("d81e820100"))
Expand Down

0 comments on commit b4f7fce

Please sign in to comment.