diff --git a/libs/filamat/src/eiff/Flattener.h b/libs/filamat/src/eiff/Flattener.h index e43cdb7681..4b951108f4 100644 --- a/libs/filamat/src/eiff/Flattener.h +++ b/libs/filamat/src/eiff/Flattener.h @@ -34,44 +34,54 @@ using namespace utils; +namespace { +constexpr uint8_t FAKE_DRY_RUNNER_START_ADDR = 0x1; +} // anonymous + namespace filamat { class Flattener { public: explicit Flattener(uint8_t* dst) : mCursor(dst), mStart(dst){} + // DryRunner is used to compute the size of the flattened output but not actually carry out + // flattening. If we set mStart = nullptr and mEnd=nullptr, we would hit an error about + // offsetting on null when ubsan is enabled. Instead we point mStart to a fake address, and + // mCursor is offset from that. static Flattener& getDryRunner() { static Flattener dryRunner = Flattener(nullptr); - dryRunner.mStart = nullptr; - dryRunner.mCursor = nullptr; + dryRunner.mStart = (uint8_t*) FAKE_DRY_RUNNER_START_ADDR; + dryRunner.mCursor = (uint8_t*) FAKE_DRY_RUNNER_START_ADDR; dryRunner.mOffsetPlaceholders.clear(); dryRunner.mSizePlaceholders.clear(); dryRunner.mValuePlaceholders.clear(); return dryRunner; } - bool isDryRunner() { return mStart == nullptr;} + bool isDryRunner() { + return mStart == (uint8_t*) FAKE_DRY_RUNNER_START_ADDR; + } size_t getBytesWritten() { return mCursor - mStart; } void writeBool(bool b) { - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = static_cast(b); } mCursor += 1; } void writeUint8(uint8_t i) { - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = i; } mCursor += 1; } void writeUint16(uint16_t i) { - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = static_cast( i & 0xff); mCursor[1] = static_cast((i >> 8) & 0xff); } @@ -79,7 +89,7 @@ public: } void writeUint32(uint32_t i) { - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = static_cast( i & 0xff); mCursor[1] = static_cast((i >> 8) & 0xff); mCursor[2] = static_cast((i >> 16) & 0xff); @@ -89,7 +99,7 @@ public: } void writeUint64(uint64_t i) { - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = static_cast( i & 0xff); mCursor[1] = static_cast((i >> 8) & 0xff); mCursor[2] = static_cast((i >> 16) & 0xff); @@ -104,7 +114,7 @@ public: void writeString(const char* str) { size_t const len = strlen(str); - if (mStart != nullptr) { + if (!isDryRunner()) { strcpy(reinterpret_cast(mCursor), str); } mCursor += len + 1; @@ -112,7 +122,7 @@ public: void writeString(std::string_view str) { size_t const len = str.length(); - if (mStart != nullptr) { + if (!isDryRunner()) { memcpy(reinterpret_cast(mCursor), str.data(), len); mCursor[len] = 0; } @@ -121,14 +131,14 @@ public: void writeBlob(const char* blob, size_t nbytes) { writeUint64(nbytes); - if (mStart != nullptr) { + if (!isDryRunner()) { memcpy(reinterpret_cast(mCursor), blob, nbytes); } mCursor += nbytes; } void writeRaw(const char* raw, size_t nbytes) { - if (mStart != nullptr) { + if (!isDryRunner()) { memcpy(reinterpret_cast(mCursor), raw, nbytes); } mCursor += nbytes; @@ -136,7 +146,7 @@ public: void writeSizePlaceholder() { mSizePlaceholders.push_back(mCursor); - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = 0; mCursor[1] = 0; mCursor[2] = 0; @@ -164,7 +174,7 @@ public: mSizePlaceholders.pop_back(); // -4 to account for the 4 bytes we are about to write. uint32_t const size = static_cast(mCursor - dst - 4); - if (mStart != nullptr) { + if (!isDryRunner()) { dst[0] = static_cast( size & 0xff); dst[1] = static_cast((size >> 8) & 0xff); dst[2] = static_cast((size >> 16) & 0xff); @@ -175,7 +185,7 @@ public: void writeOffsetplaceholder(size_t index) { mOffsetPlaceholders.insert(std::pair(index, mCursor)); - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = 0x0; mCursor[1] = 0x0; mCursor[2] = 0x0; @@ -185,7 +195,7 @@ public: } void writeOffsets(uint32_t forIndex) { - if (mStart == nullptr) { + if (isDryRunner()) { return; } @@ -209,7 +219,7 @@ public: void writeValuePlaceholder() { mValuePlaceholders.push_back(mCursor); - if (mStart != nullptr) { + if (!isDryRunner()) { mCursor[0] = 0; mCursor[1] = 0; mCursor[2] = 0; @@ -228,7 +238,7 @@ public: uint8_t* dst = mValuePlaceholders.back(); mValuePlaceholders.pop_back(); - if (mStart != nullptr) { + if (!isDryRunner()) { dst[0] = static_cast( v & 0xff); dst[1] = static_cast((v >> 8) & 0xff); dst[2] = static_cast((v >> 16) & 0xff);