diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index e816c814..ca6cf983 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -27,7 +27,7 @@ cdef extern from "pack.h": int msgpack_pack_false(msgpack_packer* pk) except -1 int msgpack_pack_long_long(msgpack_packer* pk, long long d) except -1 int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d) except -1 - int msgpack_pack_float(msgpack_packer* pk, float d) except -1 + int msgpack_pack_float(msgpack_packer* pk, double d) except -1 int msgpack_pack_double(msgpack_packer* pk, double d) except -1 int msgpack_pack_array(msgpack_packer* pk, size_t l) except -1 int msgpack_pack_map(msgpack_packer* pk, size_t l) except -1 @@ -179,7 +179,7 @@ cdef class Packer: raise OverflowError("Integer value out of range") elif PyFloat_CheckExact(o) if strict else PyFloat_Check(o): if self.use_float: - msgpack_pack_float(&self.pk, o) + msgpack_pack_float(&self.pk, o) else: msgpack_pack_double(&self.pk, o) elif PyBytesLike_CheckExact(o) if strict else PyBytesLike_Check(o): diff --git a/msgpack/pack_template.h b/msgpack/pack_template.h index e02ec324..6e9d9ba4 100644 --- a/msgpack/pack_template.h +++ b/msgpack/pack_template.h @@ -342,15 +342,15 @@ static inline int msgpack_pack_unsigned_long_long(msgpack_packer* x, unsigned lo * Float */ -static inline int msgpack_pack_float(msgpack_packer* x, float d) +static inline int msgpack_pack_float(msgpack_packer* x, double d) { unsigned char buf[5]; buf[0] = 0xca; #if PY_VERSION_HEX >= 0x030B00A7 - PyFloat_Pack4(d, (char *)&buf[1], 0); + if (PyFloat_Pack4(d, (char *)&buf[1], 0) < 0) { return -1; } #else - _PyFloat_Pack4(d, &buf[1], 0); + if (_PyFloat_Pack4(d, &buf[1], 0) < 0) { return -1; } #endif msgpack_pack_append_buffer(x, buf, 5); } diff --git a/test/test_limits.py b/test/test_limits.py index bb554d68..ef894c11 100644 --- a/test/test_limits.py +++ b/test/test_limits.py @@ -27,6 +27,17 @@ def test_integer(): packb(x + 1) +def test_single_float(): + x = 3.4028234663852886e38 # FLT_MAX + assert unpackb(packb(x, use_single_float=True)) == x + with pytest.raises(PackOverflowError): + packb(x * 2, use_single_float=True) + + # Infinities are representable in single precision, so they must not raise. + for x in (float("inf"), float("-inf")): + assert unpackb(packb(x, use_single_float=True)) == x + + def test_array_header(): packer = Packer() packer.pack_array_header(2**32 - 1)