MessagePack: serialize round floats as integers (fixes #1718)

This commit is contained in:
Benoit Blanchon
2022-02-28 18:00:43 +01:00
parent ff06292d74
commit e3e375f5cd
3 changed files with 24 additions and 7 deletions

View File

@ -7,6 +7,7 @@ HEAD
* Fix `call of overloaded 'String(const char*, int)' is ambiguous` * Fix `call of overloaded 'String(const char*, int)' is ambiguous`
* Fix `JsonString` operator `==` and `!=` for non-zero-terminated string * Fix `JsonString` operator `==` and `!=` for non-zero-terminated string
* Fix `-Wsign-conversion` on GCC 8 (issue #1715) * Fix `-Wsign-conversion` on GCC 8 (issue #1715)
* MessagePack: serialize round floats as integers (issue #1718)
v6.19.2 (2022-02-14) v6.19.2 (2022-02-14)
------- -------

View File

@ -144,4 +144,18 @@ TEST_CASE("serialize MsgPack value") {
checkVariant(serialized("\xDA\xFF\xFF"), "\xDA\xFF\xFF"); checkVariant(serialized("\xDA\xFF\xFF"), "\xDA\xFF\xFF");
checkVariant(serialized("\xDB\x00\x01\x00\x00", 5), "\xDB\x00\x01\x00\x00"); checkVariant(serialized("\xDB\x00\x01\x00\x00", 5), "\xDB\x00\x01\x00\x00");
} }
SECTION("serialize round double as integer") { // Issue #1718
checkVariant(-32768.0, "\xD1\x80\x00");
checkVariant(-129.0, "\xD1\xFF\x7F");
checkVariant(-128.0, "\xD0\x80");
checkVariant(-33.0, "\xD0\xDF");
checkVariant(-32.0, "\xE0");
checkVariant(-1.0, "\xFF");
checkVariant(0.0, "\x00");
checkVariant(127.0, "\x7F");
checkVariant(128.0, "\xCC\x80");
checkVariant(255.0, "\xCC\xFF");
checkVariant(256.0, "\xCD\x01\x00");
}
} }

View File

@ -23,6 +23,11 @@ class MsgPackSerializer : public Visitor<size_t> {
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) { typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
if (canConvertNumber<Integer>(value32)) {
Integer truncatedValue = Integer(value32);
if (value32 == T(truncatedValue))
return visitSignedInteger(truncatedValue);
}
writeByte(0xCA); writeByte(0xCA);
writeInteger(value32); writeInteger(value32);
return bytesWritten(); return bytesWritten();
@ -32,13 +37,10 @@ class MsgPackSerializer : public Visitor<size_t> {
ARDUINOJSON_NO_SANITIZE("float-cast-overflow") ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) { typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
float value32 = float(value64); float value32 = float(value64);
if (value32 == value64) { if (value32 == value64)
writeByte(0xCA); return visitFloat(value32);
writeInteger(value32); writeByte(0xCB);
} else { writeInteger(value64);
writeByte(0xCB);
writeInteger(value64);
}
return bytesWritten(); return bytesWritten();
} }