summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorInada Naoki <songofacandy@gmail.com>2020-12-18 14:21:27 +0900
committerGitHub <noreply@github.com>2020-12-18 14:21:27 +0900
commit753b3706d80a7bc5a29147730804e867b97eee57 (patch)
tree6150edca595bdf419644aa53c5e72db2554dc6e4
parent8029f95516dbfddf2fea61efb06dc08ded84aab7 (diff)
downloadmsgpack-python-753b3706d80a7bc5a29147730804e867b97eee57.tar.gz
Fix overflow in unpacking timestamp to datetime (#452)
-rw-r--r--msgpack/unpack.h6
-rw-r--r--test/test_timestamp.py11
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