-
Notifications
You must be signed in to change notification settings - Fork 918
Closed
Description
Problem appears when using msgpack::type::variant serialization for float number with zero decimal part.
Here motivation example:
# include <msgpack.hpp>
# include <cassert>
int main() {
msgpack::type::variant val(212.f);
std::stringstream ss;
msgpack::pack(ss, val);
auto unpacked = msgpack::unpack(ss.str().data(), ss.str().size());
auto obj = unpacked.get();
msgpack::type::variant restored_val;
obj.convert(restored_val);
assert(val == restored_val);//failed here
}
The reason for the failed assert is different types of variant’s values.
There are float type of val and uint64 type of the restored_val
I’ve found out that positive float number with zero decimal part is stored as uint64, hence when it is deserialized, it turns into an uint64 number.
As I know, it happens in line 1165 of msgpack/v1/pack.hpp, here:
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_double(double d)
{
if(d == d) { // check for nan
// compare d to limits to avoid undefined behaviour
if(d >= 0 && d <= double(std::numeric_limits<uint64_t>::max()) && d == double(uint64_t(d))) {
pack_imp_uint64(uint64_t(d));
return *this;
} else if(d < 0 && d >= double(std::numeric_limits<int64_t>::min()) && d == double(int64_t(d))) {
pack_imp_int64(int64_t(d));
return *this;
}
}
//other code
Here https://gist.github.com/redboltz/672c5af16b2907488977 same problem.
Thank you for response.
msgpack version: 6.0.0
OS: Windows 10
Metadata
Metadata
Assignees
Labels
No labels