From 46a7331754ac8f2a65f42317526e2b619330f357 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 26 Jan 2026 00:46:30 -0600 Subject: [PATCH] [ox/mc] Cleanup, fix possible overflow bug --- deps/ox/src/ox/mc/presenceindicator.cpp | 4 +- deps/ox/src/ox/mc/presenceindicator.hpp | 75 +++++++++++++------------ deps/ox/src/ox/mc/write.hpp | 7 +-- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/deps/ox/src/ox/mc/presenceindicator.cpp b/deps/ox/src/ox/mc/presenceindicator.cpp index c5055f4a..98877aae 100644 --- a/deps/ox/src/ox/mc/presenceindicator.cpp +++ b/deps/ox/src/ox/mc/presenceindicator.cpp @@ -11,7 +11,7 @@ namespace ox { -template class FieldBitmapWriterBase; -template class FieldBitmapWriterBase; +template class FieldBitmapWriterBase; +template class FieldBitmapWriterBase; } diff --git a/deps/ox/src/ox/mc/presenceindicator.hpp b/deps/ox/src/ox/mc/presenceindicator.hpp index bc6ed045..1288ce8c 100644 --- a/deps/ox/src/ox/mc/presenceindicator.hpp +++ b/deps/ox/src/ox/mc/presenceindicator.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -21,18 +22,18 @@ namespace ox { template class FieldBitmapReader { protected: - mutable std::size_t m_mapBlockIdx = ~std::size_t{0}; + mutable size_t m_mapBlockIdx = ~size_t{0}; mutable uint64_t m_mapBlock = 0; - std::size_t m_mapStart = 0; + size_t m_mapStart = 0; Reader &m_reader; public: explicit constexpr FieldBitmapReader(Reader &reader) noexcept; - constexpr Result get(std::size_t i) const noexcept; + constexpr Result get(size_t idx) const noexcept; private: - constexpr ox::Error loadMapBlock(std::size_t id) const noexcept; + constexpr Error loadMapBlock(size_t idx) const noexcept; }; @@ -43,7 +44,7 @@ constexpr FieldBitmapReader::FieldBitmapReader(Reader &reader) noexcept: } template -constexpr Result FieldBitmapReader::get(std::size_t idx) const noexcept { +constexpr Result FieldBitmapReader::get(size_t idx) const noexcept { constexpr auto blockBits = sizeof(m_mapBlock); auto const blockIdx = idx / blockBits; if (m_mapBlockIdx != blockIdx) [[unlikely]] { @@ -54,15 +55,15 @@ constexpr Result FieldBitmapReader::get(std::size_t idx) const noe } template -constexpr ox::Error FieldBitmapReader::loadMapBlock(std::size_t idx) const noexcept { +constexpr Error FieldBitmapReader::loadMapBlock(size_t const idx) const noexcept { OX_REQUIRE(g, m_reader.tellg()); OX_RETURN_ERROR(m_reader.seekg(static_cast(m_mapStart + idx), ox::ios_base::beg)); - ox::Array mapBlock{}; + Array mapBlock{}; OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock))); // Warning: narrow-conv OX_RETURN_ERROR(m_reader.seekg(static_cast(g), ox::ios_base::beg)); m_mapBlock = 0; - for (auto i = 0ull; auto b : mapBlock) { + for (uint64_t i{}; auto b : mapBlock) { m_mapBlock |= static_cast(std::bit_cast(b)) << i; i += 8; } @@ -74,17 +75,17 @@ constexpr ox::Error FieldBitmapReader::loadMapBlock(std::size_t idx) con template class FieldBitmapWriterBase { protected: - T m_map = nullptr; - std::size_t m_mapLen = 0; + Span m_map; + size_t m_mapLen = 0; public: - constexpr FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept; + explicit constexpr FieldBitmapWriterBase(Span map) noexcept; - constexpr auto setBuffer(T map, std::size_t maxLen) noexcept; + constexpr auto setBuffer(Span map) noexcept; - constexpr Result get(std::size_t i) const noexcept; + constexpr Result get(size_t i) const noexcept; - constexpr void setFields(int) noexcept; + constexpr Error setFields(int) noexcept; constexpr void setMaxLen(int) noexcept; @@ -94,34 +95,38 @@ class FieldBitmapWriterBase { }; template -constexpr FieldBitmapWriterBase::FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept { - m_map = map; - m_mapLen = maxLen; +constexpr FieldBitmapWriterBase::FieldBitmapWriterBase(Span map) noexcept: + m_map(map), + m_mapLen(m_map.size()) { } template -constexpr auto FieldBitmapWriterBase::setBuffer(T map, std::size_t maxLen) noexcept { +constexpr auto FieldBitmapWriterBase::setBuffer(Span map) noexcept { m_map = map; - m_mapLen = maxLen; + m_mapLen = map.size(); } template -constexpr Result FieldBitmapWriterBase::get(std::size_t i) const noexcept { +constexpr Result FieldBitmapWriterBase::get(size_t const i) const noexcept { if (i / 8 < m_mapLen) { return (m_map[i / 8] >> (i % 8)) & 1; } else { - return ox::Error(McPresenceMapOverflow); + return Error{McPresenceMapOverflow}; } } template -constexpr void FieldBitmapWriterBase::setFields(int fields) noexcept { - m_mapLen = static_cast((fields / 8 + 1) - (fields % 8 == 0)); +constexpr Error FieldBitmapWriterBase::setFields(int const fields) noexcept { + m_mapLen = static_cast((fields / 8 + 1) - (fields % 8 == 0)); + if (m_mapLen > m_map.size()) [[unlikely]] { + return Error{McPresenceMapOverflow}; + } + return {}; } template -constexpr void FieldBitmapWriterBase::setMaxLen(int maxLen) noexcept { - m_mapLen = static_cast(maxLen); +constexpr void FieldBitmapWriterBase::setMaxLen(int const maxLen) noexcept { + m_mapLen = static_cast(maxLen); } template @@ -129,34 +134,32 @@ constexpr int64_t FieldBitmapWriterBase::getMaxLen() const noexcept { return static_cast(m_mapLen); } -extern template class FieldBitmapWriterBase; -extern template class FieldBitmapWriterBase; +extern template class FieldBitmapWriterBase; +extern template class FieldBitmapWriterBase; -class FieldBitmap: public FieldBitmapWriterBase { +class FieldBitmap: public FieldBitmapWriterBase { public: - constexpr FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept; + explicit constexpr FieldBitmap(Span map) noexcept; - constexpr Error set(std::size_t i, bool on) noexcept; + constexpr Error set(size_t i, bool on) noexcept; }; -constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept: - FieldBitmapWriterBase(map, maxLen) { +constexpr FieldBitmap::FieldBitmap(Span map) noexcept: + FieldBitmapWriterBase(map) { } -constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept { +constexpr Error FieldBitmap::set(size_t const i, bool const on) noexcept { if (i / 8 < m_mapLen) { -OX_ALLOW_UNSAFE_BUFFERS_BEGIN if (on) { m_map[i / 8] |= 1 << (i % 8); } else { m_map[i / 8] &= ~static_cast(1 << (i % 8)); } -OX_ALLOW_UNSAFE_BUFFERS_END return {}; } else { - return ox::Error(McPresenceMapOverflow); + return Error(McPresenceMapOverflow); } } diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index ddc18236..4adbc16c 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -132,7 +132,7 @@ extern template class ModelHandlerInterface>; template constexpr MetalClawWriter::MetalClawWriter(Writer &writer, Optional const &unionIdx) noexcept: - m_fieldPresence(m_presenceMapBuff.data(), m_presenceMapBuff.size()), + m_fieldPresence(m_presenceMapBuff), m_unionIdx(unionIdx), m_writerBeginP(writer.tellp()), m_writer(writer) { @@ -369,9 +369,8 @@ constexpr Error MetalClawWriter::setTypeInfo( auto const fieldPresenceLen = (fields - 1) / 8 + 1; OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen)); m_presenceMapBuff.resize(fieldPresenceLen); - m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size()); - m_fieldPresence.setFields(static_cast(fields)); - return {}; + m_fieldPresence.setBuffer(m_presenceMapBuff); + return m_fieldPresence.setFields(static_cast(fields)); } template