From 8a8dc4e111af0e93ab1a4cf58a57977e64ca465e Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Thu, 16 Nov 2017 14:19:31 -0800 Subject: [PATCH] Fixed potential strict-aliasing violation in big-endian code. Also added a test. Tested on: Linux. Change-Id: I7b3230f8f6043eec139d5e3e8c9cb45814124274 --- include/flatbuffers/base.h | 18 ++++++++++++------ tests/test.cpp | 11 +++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index 538784ac8..e3dfbfd8f 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -186,14 +186,20 @@ template T EndianSwap(T t) { if (sizeof(T) == 1) { // Compile-time if-then's. return t; } else if (sizeof(T) == 2) { - auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); + union { T t; uint16_t i; } u; + u.t = t; + u.i = FLATBUFFERS_BYTESWAP16(u.i); + return u.t; } else if (sizeof(T) == 4) { - auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); + union { T t; uint32_t i; } u; + u.t = t; + u.i = FLATBUFFERS_BYTESWAP32(u.i); + return u.t; } else if (sizeof(T) == 8) { - auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); + union { T t; uint64_t i; } u; + u.t = t; + u.i = FLATBUFFERS_BYTESWAP64(u.i); + return u.t; } else { assert(0); } diff --git a/tests/test.cpp b/tests/test.cpp index e2a3e1f66..dd76c0d4b 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1803,6 +1803,16 @@ void TypeAliasesTest() TEST_EQ(sizeof(ta->f64()), 8); } +void EndianSwapTest() { + TEST_EQ(flatbuffers::EndianSwap(static_cast(0x1234)), + 0x3412); + TEST_EQ(flatbuffers::EndianSwap(static_cast(0x12345678)), + 0x78563412); + TEST_EQ(flatbuffers::EndianSwap(static_cast(0x1234567890ABCDEF)), + 0xEFCDAB9078563412); + TEST_EQ(flatbuffers::EndianSwap(flatbuffers::EndianSwap(3.14f)), 3.14f); +} + int main(int /*argc*/, const char * /*argv*/[]) { #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ defined(_MSC_VER) && defined(_DEBUG) @@ -1866,6 +1876,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { ConformTest(); ParseProtoBufAsciiTest(); TypeAliasesTest(); + EndianSwapTest(); FlexBuffersTest();