Fixed potential strict-aliasing violation in big-endian code.

Also added a test.

Tested on: Linux.

Change-Id: I7b3230f8f6043eec139d5e3e8c9cb45814124274
parent 7e803c41
...@@ -186,14 +186,20 @@ template<typename T> T EndianSwap(T t) { ...@@ -186,14 +186,20 @@ template<typename T> T EndianSwap(T t) {
if (sizeof(T) == 1) { // Compile-time if-then's. if (sizeof(T) == 1) { // Compile-time if-then's.
return t; return t;
} else if (sizeof(T) == 2) { } else if (sizeof(T) == 2) {
auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast<uint16_t *>(&t)); union { T t; uint16_t i; } u;
return *reinterpret_cast<T *>(&r); u.t = t;
u.i = FLATBUFFERS_BYTESWAP16(u.i);
return u.t;
} else if (sizeof(T) == 4) { } else if (sizeof(T) == 4) {
auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast<uint32_t *>(&t)); union { T t; uint32_t i; } u;
return *reinterpret_cast<T *>(&r); u.t = t;
u.i = FLATBUFFERS_BYTESWAP32(u.i);
return u.t;
} else if (sizeof(T) == 8) { } else if (sizeof(T) == 8) {
auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast<uint64_t *>(&t)); union { T t; uint64_t i; } u;
return *reinterpret_cast<T *>(&r); u.t = t;
u.i = FLATBUFFERS_BYTESWAP64(u.i);
return u.t;
} else { } else {
assert(0); assert(0);
} }
......
...@@ -1803,6 +1803,16 @@ void TypeAliasesTest() ...@@ -1803,6 +1803,16 @@ void TypeAliasesTest()
TEST_EQ(sizeof(ta->f64()), 8); TEST_EQ(sizeof(ta->f64()), 8);
} }
void EndianSwapTest() {
TEST_EQ(flatbuffers::EndianSwap(static_cast<int16_t>(0x1234)),
0x3412);
TEST_EQ(flatbuffers::EndianSwap(static_cast<int32_t>(0x12345678)),
0x78563412);
TEST_EQ(flatbuffers::EndianSwap(static_cast<int64_t>(0x1234567890ABCDEF)),
0xEFCDAB9078563412);
TEST_EQ(flatbuffers::EndianSwap(flatbuffers::EndianSwap(3.14f)), 3.14f);
}
int main(int /*argc*/, const char * /*argv*/[]) { int main(int /*argc*/, const char * /*argv*/[]) {
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
defined(_MSC_VER) && defined(_DEBUG) defined(_MSC_VER) && defined(_DEBUG)
...@@ -1866,6 +1876,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { ...@@ -1866,6 +1876,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
ConformTest(); ConformTest();
ParseProtoBufAsciiTest(); ParseProtoBufAsciiTest();
TypeAliasesTest(); TypeAliasesTest();
EndianSwapTest();
FlexBuffersTest(); FlexBuffersTest();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment