From c78d3cf638410e1441c18dfde98382a79099c76f Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 26 Nov 2024 23:31:34 -0600 Subject: [PATCH] [ox] Add more unsafe buffer exceptions --- deps/ox/src/ox/logconn/circularbuff.hpp | 4 ++++ deps/ox/src/ox/mc/intops.hpp | 10 +++++----- deps/ox/src/ox/mc/presenceindicator.hpp | 2 ++ deps/ox/src/ox/mc/read.hpp | 10 ++++++---- deps/ox/src/ox/mc/write.hpp | 14 ++++++++------ deps/ox/src/ox/oc/read.hpp | 4 ++++ deps/ox/src/ox/oc/write.hpp | 2 ++ deps/ox/src/ox/std/def.hpp | 4 ++++ 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/deps/ox/src/ox/logconn/circularbuff.hpp b/deps/ox/src/ox/logconn/circularbuff.hpp index 96e5fb8c..1100c10a 100644 --- a/deps/ox/src/ox/logconn/circularbuff.hpp +++ b/deps/ox/src/ox/logconn/circularbuff.hpp @@ -45,6 +45,7 @@ class CirculerBuffer { if (sz > avail()) { return OxError(1, "Insufficient space in buffer"); } +OX_ALLOW_UNSAFE_BUFFERS_BEGIN // write seg 1 const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt); ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz); @@ -56,6 +57,7 @@ class CirculerBuffer { ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz); oxAssert(m_buff[0] == buff[seg1Sz], "break"); } +OX_ALLOW_UNSAFE_BUFFERS_END return {}; } @@ -90,7 +92,9 @@ class CirculerBuffer { m_readPt -= m_buff.size(); // read seg 2 const auto seg2Sz = bytesRead - seg1Sz; +OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz); +OX_ALLOW_UNSAFE_BUFFERS_END } return bytesRead; } diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index 501cda87..567af5c6 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -57,7 +57,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31); static_assert(highestBit(uint64_t(1) << 63) == 63); struct McInt { - uint8_t data[9] = {}; + ox::Array data{}; // length of integer in bytes std::size_t length = 0; }; @@ -104,7 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept { auto intermediate = static_cast(leVal.raw() | (negBit << (valBits - 1))) << bytes | static_cast(bytesIndicator); - ox::memcpy(out.data, &intermediate, sizeof(intermediate)); + ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate)); } out.length = bytes; } @@ -160,7 +160,7 @@ constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe ox::Array d = {}; //d[0] = decoded & 0xffff'ffff; //d[1] = decoded >> 32; - ox::memcpy(d.data(), &decoded, sizeof(decoded)); + ox::memcpy(&d[0], &decoded, sizeof(decoded)); auto bit = negBit; for (; bit < ox::min(Bits, 32); ++bit) { d[0] |= 1 << bit; @@ -175,7 +175,7 @@ constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe d[0] = d[1]; d[1] = d0Tmp; } - ox::memcpy(&out, d.data(), sizeof(out)); + ox::memcpy(&out, &d[0], sizeof(out)); return out; } } @@ -185,7 +185,7 @@ constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe template Result decodeInteger(McInt m) noexcept { std::size_t bytesRead{}; - BufferReader br({reinterpret_cast(m.data), 9}); + BufferReader br({reinterpret_cast(m.data.data()), 9}); return decodeInteger(br, &bytesRead); } diff --git a/deps/ox/src/ox/mc/presenceindicator.hpp b/deps/ox/src/ox/mc/presenceindicator.hpp index 8a5b3128..f9f02c9e 100644 --- a/deps/ox/src/ox/mc/presenceindicator.hpp +++ b/deps/ox/src/ox/mc/presenceindicator.hpp @@ -147,11 +147,13 @@ constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept: constexpr Error FieldBitmap::set(std::size_t i, bool 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 OxError(McPresenceMapOverflow); diff --git a/deps/ox/src/ox/mc/read.hpp b/deps/ox/src/ox/mc/read.hpp index cbb472af..e0534d06 100644 --- a/deps/ox/src/ox/mc/read.hpp +++ b/deps/ox/src/ox/mc/read.hpp @@ -214,7 +214,9 @@ constexpr Error MetalClawReaderTemplate::field(const char *name, auto *v auto &handler = *reader.interface(); oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast(len))); for (std::size_t i = 0; i < len; ++i) { +OX_ALLOW_UNSAFE_BUFFERS_BEGIN oxReturnError(handler.field({}, &val[i])); +OX_ALLOW_UNSAFE_BUFFERS_END } } else { oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen); @@ -380,9 +382,9 @@ constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char // re-allocate in case too small safeDelete(*val); *val = new char[size + 1]; - auto data = *val; + auto data = ox::Span{*val, size + 1}; // read the string - oxReturnError(m_reader.read(data, size)); + oxReturnError(m_reader.read(data.data(), size)); data[size] = 0; } ++m_field; @@ -402,9 +404,9 @@ constexpr Error MetalClawReaderTemplate::fieldCString(const char*, char *val = new char[size + 1]; buffLen = size + 1; } - auto data = *val; + auto data = ox::Span{*val, size + 1}; // read the string - oxReturnError(m_reader.read(data, size)); + oxReturnError(m_reader.read(data.data(), size)); data[size] = 0; } else { auto data = *val; diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index 44a18812..b63480ef 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -117,7 +117,7 @@ class MetalClawWriter { bool fieldSet = false; if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { auto mi = mc::encodeInteger(val); - oxReturnError(m_writer.write(reinterpret_cast(mi.data), mi.length)); + oxReturnError(m_writer.write(reinterpret_cast(mi.data.data()), mi.length)); fieldSet = true; } oxReturnError(m_fieldPresence.set(static_cast(m_field), fieldSet)); @@ -194,7 +194,7 @@ constexpr Error MetalClawWriter::field(const char*, const BasicStringlen() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { // write the length const auto strLen = mc::encodeInteger(val->len()); - oxReturnError(m_writer.write(reinterpret_cast(strLen.data), strLen.length)); + oxReturnError(m_writer.write(reinterpret_cast(strLen.data.data()), strLen.length)); // write the string oxReturnError(m_writer.write(val->c_str(), static_cast(val->len()))); fieldSet = true; @@ -217,7 +217,7 @@ constexpr Error MetalClawWriter::fieldCString(const char*, const char *c const auto strLen = *val ? ox::strlen(*val) : 0; // write the length const auto strLenBuff = mc::encodeInteger(strLen); - oxReturnError(m_writer.write(reinterpret_cast(strLenBuff.data), strLenBuff.length)); + oxReturnError(m_writer.write(reinterpret_cast(strLenBuff.data.data()), strLenBuff.length)); // write the string oxReturnError(m_writer.write(*val, static_cast(strLen))); fieldSet = true; @@ -243,7 +243,7 @@ constexpr Error MetalClawWriter::fieldCString(const char*, const char *v if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { // write the length const auto strLenBuff = mc::encodeInteger(strLen); - oxReturnError(m_writer.write(reinterpret_cast(strLenBuff.data), strLenBuff.length)); + oxReturnError(m_writer.write(reinterpret_cast(strLenBuff.data.data()), strLenBuff.length)); // write the string oxReturnError(m_writer.write(val, static_cast(strLen))); fieldSet = true; @@ -298,14 +298,16 @@ constexpr Error MetalClawWriter::field(const char*, const T *val, std::s if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { // write the length const auto arrLen = mc::encodeInteger(len); - oxReturnError(m_writer.write(reinterpret_cast(arrLen.data), arrLen.length)); + oxReturnError(m_writer.write(reinterpret_cast(arrLen.data.data()), arrLen.length)); auto const writeIdx = m_writer.tellp(); MetalClawWriter writer(m_writer); ModelHandlerInterface handler{&writer}; oxReturnError(handler.template setTypeInfo("List", 0, {}, static_cast(len))); // write the array for (std::size_t i = 0; i < len; ++i) { +OX_ALLOW_UNSAFE_BUFFERS_BEGIN oxReturnError(handler.field("", &val[i])); +OX_ALLOW_UNSAFE_BUFFERS_END } oxReturnError(writer.finalize()); fieldSet = writeIdx != m_writer.tellp(); @@ -324,7 +326,7 @@ constexpr Error MetalClawWriter::field(const char*, const HashMap(arrLen.data), arrLen.length)); + oxReturnError(m_writer.write(reinterpret_cast(arrLen.data.data()), arrLen.length)); // write map MetalClawWriter writer(m_writer); ModelHandlerInterface handler{&writer}; diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index 2db945a7..9f220c3d 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -244,7 +244,9 @@ Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noex OrganicClawReader r(srcVal); ModelHandlerInterface handler{&r}; for (decltype(srcSize) i = 0; i < srcSize; ++i) { +OX_ALLOW_UNSAFE_BUFFERS_BEGIN oxReturnError(handler.field("", &val[i])); +OX_ALLOW_UNSAFE_BUFFERS_END } return OxError(0); } @@ -272,7 +274,9 @@ Error readOC(BufferView buff, auto &val) noexcept { Json::Value doc; Json::CharReaderBuilder parserBuilder; auto parser = UniquePtr(parserBuilder.newCharReader()); +OX_ALLOW_UNSAFE_BUFFERS_BEGIN if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) { +OX_ALLOW_UNSAFE_BUFFERS_END return OxError(1, "Could not parse JSON"); } OrganicClawReader reader(buff.data(), buff.size()); diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index 006bfd63..d87b0f7d 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -200,7 +200,9 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n OrganicClawWriter w((Json::Value(Json::arrayValue))); ModelHandlerInterface handler{&w}; for (std::size_t i = 0; i < len; ++i) { +OX_ALLOW_UNSAFE_BUFFERS_BEGIN oxReturnError(handler.field({}, &val[i])); +OX_ALLOW_UNSAFE_BUFFERS_END } value(key) = w.m_json; } diff --git a/deps/ox/src/ox/std/def.hpp b/deps/ox/src/ox/std/def.hpp index 9d57f385..ab848ca0 100644 --- a/deps/ox/src/ox/std/def.hpp +++ b/deps/ox/src/ox/std/def.hpp @@ -77,9 +77,13 @@ constexpr void oxAssert(const ox::Error&, const char*) noexcept {} OX_PRAGMA(clang diagnostic push) \ OX_PRAGMA(clang diagnostic ignored #warnoption) #define OX_CLANG_NOWARN_END OX_PRAGMA(clang diagnostic pop) +#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) +#define OX_ALLOW_UNSAFE_BUFFERS_END OX_CLANG_NOWARN_END #else #define OX_CLANG_NOWARN_BEGIN(warnoption) #define OX_CLANG_NOWARN_END +#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN +#define OX_ALLOW_UNSAFE_BUFFERS_END #endif /**