From 326c69896bb5cbf98e49e3540f5b9a746d48ddba Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 14 Mar 2019 19:35:58 -0400 Subject: [PATCH] stream: Get rid of undefined behavior It's undefined behavior to cast down to any other type and dereference that pointer unless: 1. It's similar (*extremely* vague definition at face value, see below for clarification) 2. The casted to type is either the signed/unsigned variant of the original type. (e.g. it's fine to cast an int* to an unsigned int* and vice-versa). 3. The casted to pointer type is either std::byte*, char*, or unsigned char*. With regards to type similarity, two types (X and Y) are considered "similar" if: 1. They're the same type (naturally) 2. They're both pointers and the pointed-to types are similar (basically 1. but for pointers) 3. They're both pointers to members of the same class and the types of the pointed-to members are similar in type. 4. They're both arrays of the same size or both arrays of unknown size *and* the array element types are similar. Plus, doing it this way doesn't do a byte-by-byte appending to the underlying std::vector and instead allocates all the necessary memory up front and slaps the elements at the end of it. --- src/stream.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/stream.cpp b/src/stream.cpp index aae5a9e..bf0eaf3 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -24,21 +24,18 @@ void Stream::Write(std::string string) { } void Stream::Write(u64 value) { - const auto mem{reinterpret_cast(&value)}; - Write(mem[0]); - Write(mem[1]); + const auto* const mem = reinterpret_cast(&value); + bytes.insert(bytes.end(), mem, mem + sizeof(u64)); } void Stream::Write(u32 value) { - const auto mem{reinterpret_cast(&value)}; - Write(mem[0]); - Write(mem[1]); + const auto* const mem = reinterpret_cast(&value); + bytes.insert(bytes.end(), mem, mem + sizeof(u32)); } void Stream::Write(u16 value) { - const auto mem{reinterpret_cast(&value)}; - Write(mem[0]); - Write(mem[1]); + const auto* const mem{reinterpret_cast(&value)}; + bytes.insert(bytes.end(), mem, mem + sizeof(u16)); } void Stream::Write(u8 value) {