Skip to content

Commit

Permalink
Convert OverflowError and OSError for invalid epoch-based datetime va…
Browse files Browse the repository at this point in the history
…lues
  • Loading branch information
agronholm committed Jan 16, 2024
1 parent 98bdde3 commit 4ef178b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
8 changes: 7 additions & 1 deletion cbor2/_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,13 @@ def decode_datetime_string(self) -> datetime:
def decode_epoch_datetime(self) -> datetime:
# Semantic tag 1
value = self._decode()
return self.set_shareable(datetime.fromtimestamp(value, timezone.utc))

try:
tmp = datetime.fromtimestamp(value, timezone.utc)
except (OverflowError, OSError) as exc:
raise CBORDecodeValueError("error decoding datetime from epoch") from exc

return self.set_shareable(tmp)

def decode_positive_bignum(self) -> int:
# Semantic tag 2
Expand Down
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ This library adheres to `Semantic Versioning <http://semver.org/>`_.
``CBORDecodeValueError``
- Fixed ``TypeError`` from a failed decoding of ``MIMEMessage`` not being wrapped as
``CBORDecodeValueError``
- Fixed ``OverflowError`` or ``OSError`` from a failed decoding of epoch-based ``datetime`` not
being wrapped as ``CBORDecodeValueError``

**5.5.1** (2023-11-02)

Expand Down
5 changes: 5 additions & 0 deletions source/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,11 @@ CBORDecoder_decode_epoch_datetime(CBORDecoderObject *self)
if (tuple) {
ret = PyDateTime_FromTimestamp(tuple);
Py_DECREF(tuple);
if (!ret && (
PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_OverflowError)
|| PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_OSError)
))
raise_from(_CBOR2_CBORDecodeValueError, "error decoding datetime from epoch");
}
} else {
PyErr_Format(
Expand Down
14 changes: 14 additions & 0 deletions tests/test_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,20 @@ def test_bad_datetime(impl):
assert str(excinfo.value) == "invalid datetime string: '0000-123-01'"


def test_datetime_overflow(impl):
with pytest.raises(impl.CBORDecodeError) as excinfo:
impl.loads(unhexlify("c11b9b9b9b0000000000"))

assert isinstance(excinfo.value.__cause__, OverflowError)


def test_datetime_value_too_large(impl):
with pytest.raises(impl.CBORDecodeError) as excinfo:
impl.loads(unhexlify("c11b1616161616161616161616161616"))

assert isinstance(excinfo.value.__cause__, OSError)


def test_datetime_timezone(impl):
decoded = impl.loads(b"\xc0\x78\x192018-08-02T07:00:59+00:30")
assert decoded == datetime(2018, 8, 2, 7, 0, 59, tzinfo=timezone(timedelta(minutes=30)))
Expand Down

0 comments on commit 4ef178b

Please sign in to comment.