[ox/mc] Cleanup, fix possible overflow bug
All checks were successful
Build / build (push) Successful in 1m10s

This commit is contained in:
2026-01-26 00:46:30 -06:00
parent 56c19ad2a6
commit e6fb72b09e
3 changed files with 44 additions and 42 deletions

View File

@@ -11,7 +11,7 @@
namespace ox { namespace ox {
template class FieldBitmapWriterBase<uint8_t*>; template class FieldBitmapWriterBase<uint8_t>;
template class FieldBitmapWriterBase<const uint8_t*>; template class FieldBitmapWriterBase<uint8_t const>;
} }

View File

@@ -11,6 +11,7 @@
#include <ox/std/array.hpp> #include <ox/std/array.hpp>
#include <ox/std/bit.hpp> #include <ox/std/bit.hpp>
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
#include <ox/std/span.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
#include <ox/std/reader.hpp> #include <ox/std/reader.hpp>
@@ -21,18 +22,18 @@ namespace ox {
template<Reader_c Reader> template<Reader_c Reader>
class FieldBitmapReader { class FieldBitmapReader {
protected: 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; mutable uint64_t m_mapBlock = 0;
std::size_t m_mapStart = 0; size_t m_mapStart = 0;
Reader &m_reader; Reader &m_reader;
public: public:
explicit constexpr FieldBitmapReader(Reader &reader) noexcept; explicit constexpr FieldBitmapReader(Reader &reader) noexcept;
constexpr Result<bool> get(std::size_t i) const noexcept; constexpr Result<bool> get(size_t idx) const noexcept;
private: 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<Reader>::FieldBitmapReader(Reader &reader) noexcept:
} }
template<Reader_c Reader> template<Reader_c Reader>
constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noexcept { constexpr Result<bool> FieldBitmapReader<Reader>::get(size_t idx) const noexcept {
constexpr auto blockBits = sizeof(m_mapBlock); constexpr auto blockBits = sizeof(m_mapBlock);
auto const blockIdx = idx / blockBits; auto const blockIdx = idx / blockBits;
if (m_mapBlockIdx != blockIdx) [[unlikely]] { if (m_mapBlockIdx != blockIdx) [[unlikely]] {
@@ -54,10 +55,10 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
} }
template<Reader_c Reader> template<Reader_c Reader>
constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept { constexpr Error FieldBitmapReader<Reader>::loadMapBlock(size_t const idx) const noexcept {
OX_REQUIRE(g, m_reader.tellg()); OX_REQUIRE(g, m_reader.tellg());
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg)); OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
ox::Array<char, sizeof(m_mapBlock)> mapBlock{}; Array<char, sizeof(m_mapBlock)> mapBlock{};
OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock))); OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
// Warning: narrow-conv // Warning: narrow-conv
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg)); OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
@@ -74,17 +75,17 @@ constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) con
template<typename T> template<typename T>
class FieldBitmapWriterBase { class FieldBitmapWriterBase {
protected: protected:
T m_map = nullptr; Span<T> m_map;
std::size_t m_mapLen = 0; size_t m_mapLen = 0;
public: public:
constexpr FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept; constexpr FieldBitmapWriterBase(T *map, size_t maxLen) noexcept;
constexpr auto setBuffer(T map, std::size_t maxLen) noexcept; constexpr auto setBuffer(T *map, size_t maxLen) noexcept;
constexpr Result<bool> get(std::size_t i) const noexcept; constexpr Result<bool> get(size_t i) const noexcept;
constexpr void setFields(int) noexcept; constexpr Error setFields(int) noexcept;
constexpr void setMaxLen(int) noexcept; constexpr void setMaxLen(int) noexcept;
@@ -94,34 +95,38 @@ class FieldBitmapWriterBase {
}; };
template<typename T> template<typename T>
constexpr FieldBitmapWriterBase<T>::FieldBitmapWriterBase(T map, std::size_t maxLen) noexcept { constexpr FieldBitmapWriterBase<T>::FieldBitmapWriterBase(T *map, size_t const maxLen) noexcept:
m_map = map; m_map(map, maxLen),
m_mapLen(maxLen) {
}
template<typename T>
constexpr auto FieldBitmapWriterBase<T>::setBuffer(T *map, size_t const maxLen) noexcept {
m_map = {map, maxLen};
m_mapLen = maxLen; m_mapLen = maxLen;
} }
template<typename T> template<typename T>
constexpr auto FieldBitmapWriterBase<T>::setBuffer(T map, std::size_t maxLen) noexcept { constexpr Result<bool> FieldBitmapWriterBase<T>::get(size_t const i) const noexcept {
m_map = map;
m_mapLen = maxLen;
}
template<typename T>
constexpr Result<bool> FieldBitmapWriterBase<T>::get(std::size_t i) const noexcept {
if (i / 8 < m_mapLen) { if (i / 8 < m_mapLen) {
return (m_map[i / 8] >> (i % 8)) & 1; return (m_map[i / 8] >> (i % 8)) & 1;
} else { } else {
return ox::Error(McPresenceMapOverflow); return Error{McPresenceMapOverflow};
} }
} }
template<typename T> template<typename T>
constexpr void FieldBitmapWriterBase<T>::setFields(int fields) noexcept { constexpr Error FieldBitmapWriterBase<T>::setFields(int const fields) noexcept {
m_mapLen = static_cast<std::size_t>((fields / 8 + 1) - (fields % 8 == 0)); m_mapLen = static_cast<size_t>((fields / 8 + 1) - (fields % 8 == 0));
if (m_mapLen > m_map.size()) [[unlikely]] {
return Error{McPresenceMapOverflow};
}
return {};
} }
template<typename T> template<typename T>
constexpr void FieldBitmapWriterBase<T>::setMaxLen(int maxLen) noexcept { constexpr void FieldBitmapWriterBase<T>::setMaxLen(int const maxLen) noexcept {
m_mapLen = static_cast<std::size_t>(maxLen); m_mapLen = static_cast<size_t>(maxLen);
} }
template<typename T> template<typename T>
@@ -129,34 +134,32 @@ constexpr int64_t FieldBitmapWriterBase<T>::getMaxLen() const noexcept {
return static_cast<int64_t>(m_mapLen); return static_cast<int64_t>(m_mapLen);
} }
extern template class FieldBitmapWriterBase<uint8_t*>; extern template class FieldBitmapWriterBase<uint8_t>;
extern template class FieldBitmapWriterBase<const uint8_t*>; extern template class FieldBitmapWriterBase<uint8_t const>;
class FieldBitmap: public FieldBitmapWriterBase<uint8_t*> { class FieldBitmap: public FieldBitmapWriterBase<uint8_t> {
public: public:
constexpr FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept; constexpr FieldBitmap(uint8_t *map, size_t maxLen) 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: constexpr FieldBitmap::FieldBitmap(uint8_t *map, size_t const maxLen) noexcept:
FieldBitmapWriterBase<uint8_t*>(map, maxLen) { FieldBitmapWriterBase<uint8_t>(map, maxLen) {
} }
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) { if (i / 8 < m_mapLen) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
if (on) { if (on) {
m_map[i / 8] |= 1 << (i % 8); m_map[i / 8] |= 1 << (i % 8);
} else { } else {
m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8)); m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
} }
OX_ALLOW_UNSAFE_BUFFERS_END
return {}; return {};
} else { } else {
return ox::Error(McPresenceMapOverflow); return Error(McPresenceMapOverflow);
} }
} }

View File

@@ -370,8 +370,7 @@ constexpr Error MetalClawWriter<Writer>::setTypeInfo(
OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen)); OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen));
m_presenceMapBuff.resize(fieldPresenceLen); m_presenceMapBuff.resize(fieldPresenceLen);
m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size()); m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
m_fieldPresence.setFields(static_cast<int>(fields)); return m_fieldPresence.setFields(static_cast<int>(fields));
return {};
} }
template<Writer_c Writer> template<Writer_c Writer>