diff options
author | Inada Naoki <songofacandy@gmail.com> | 2020-12-18 14:21:27 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-18 14:21:27 +0900 |
commit | 753b3706d80a7bc5a29147730804e867b97eee57 (patch) | |
tree | 6150edca595bdf419644aa53c5e72db2554dc6e4 | |
parent | 8029f95516dbfddf2fea61efb06dc08ded84aab7 (diff) | |
download | msgpack-python-753b3706d80a7bc5a29147730804e867b97eee57.tar.gz |
Fix overflow in unpacking timestamp to datetime (#452)
-rw-r--r-- | msgpack/unpack.h | 6 | ||||
-rw-r--r-- | test/test_timestamp.py | 11 |
2 files changed, 14 insertions, 3 deletions
diff --git a/msgpack/unpack.h b/msgpack/unpack.h index 868b96e..34212bc 100644 --- a/msgpack/unpack.h +++ b/msgpack/unpack.h @@ -342,21 +342,21 @@ static int unpack_callback_ext(unpack_user* u, const char* base, const char* pos py = PyObject_CallFunction(u->timestamp_t, "(Lk)", ts.tv_sec, ts.tv_nsec); } else if (u->timestamp == 3) { // datetime - // Calculate datetime using epoch + delta + // Calculate datetime using epoch + delta // due to limitations PyDateTime_FromTimestamp on Windows with negative timestamps PyObject *epoch = PyDateTimeAPI->DateTime_FromDateAndTime(1970, 1, 1, 0, 0, 0, 0, u->utc, PyDateTimeAPI->DateTimeType); if (epoch == NULL) { return -1; } - PyObject* d = PyDelta_FromDSU(0, ts.tv_sec, ts.tv_nsec / 1000); + PyObject* d = PyDelta_FromDSU(ts.tv_sec/(24*3600), ts.tv_sec%(24*3600), ts.tv_nsec / 1000); if (d == NULL) { Py_DECREF(epoch); return -1; } py = PyNumber_Add(epoch, d); - + Py_DECREF(epoch); Py_DECREF(d); } diff --git a/test/test_timestamp.py b/test/test_timestamp.py index edc488a..6a29be7 100644 --- a/test/test_timestamp.py +++ b/test/test_timestamp.py @@ -129,3 +129,14 @@ def test_pack_datetime(): assert x assert x[0] == dt assert msgpack.unpackb(packed) is None + + +@pytest.mark.skipif(sys.version_info[0] == 2, reason="datetime support is PY3+ only") +def test_issue451(): + # https://github.com/msgpack/msgpack-python/issues/451 + dt = datetime.datetime(2100, 1, 1, 1, 1, tzinfo=_utc) + packed = msgpack.packb(dt, datetime=True) + assert packed == b"\xd6\xff\xf4\x86eL" + + unpacked = msgpack.unpackb(packed, timestamp=3) + assert dt == unpacked |