[ox] Add more unsafe buffer exceptions

This commit is contained in:
Gary Talent 2024-11-26 23:31:34 -06:00
parent cee4f65d4a
commit c78d3cf638
8 changed files with 35 additions and 15 deletions

View File

@ -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;
}

View File

@ -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<uint8_t, 9> 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<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
static_cast<uint64_t>(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<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
ox::Array<uint32_t, 2> 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<std::size_t>(Bits<I>, 32); ++bit) {
d[0] |= 1 << bit;
@ -175,7 +175,7 @@ constexpr Result<I> 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<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
template<typename I>
Result<I> decodeInteger(McInt m) noexcept {
std::size_t bytesRead{};
BufferReader br({reinterpret_cast<const char*>(m.data), 9});
BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
return decodeInteger<I>(br, &bytesRead);
}

View File

@ -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<uint8_t>(1 << (i % 8));
}
OX_ALLOW_UNSAFE_BUFFERS_END
return {};
} else {
return OxError(McPresenceMapOverflow);

View File

@ -214,7 +214,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
auto &handler = *reader.interface();
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(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<Reader>::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<Reader>::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;

View File

@ -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<const char*>(mi.data), mi.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
@ -194,7 +194,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length
const auto strLen = mc::encodeInteger(val->len());
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
// write the string
oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
fieldSet = true;
@ -217,7 +217,7 @@ constexpr Error MetalClawWriter<Writer>::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<const char*>(strLenBuff.data), strLenBuff.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string
oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
fieldSet = true;
@ -243,7 +243,7 @@ constexpr Error MetalClawWriter<Writer>::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<const char*>(strLenBuff.data), strLenBuff.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string
oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
fieldSet = true;
@ -298,14 +298,16 @@ constexpr Error MetalClawWriter<Writer>::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<const char*>(arrLen.data), arrLen.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer};
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(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<Writer>::field(const char*, const HashMap<String
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<const char*>(arrLen.data), arrLen.length));
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
// write map
MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer};

View File

@ -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<Json::CharReader>(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());

View File

@ -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<OrganicClawWriter, OpType::Write> 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;
}

View File

@ -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
/**