diff --git a/deps/ox/src/ox/clargs/clargs.cpp b/deps/ox/src/ox/clargs/clargs.cpp index e72f364b..ddeebe23 100644 --- a/deps/ox/src/ox/clargs/clargs.cpp +++ b/deps/ox/src/ox/clargs/clargs.cpp @@ -29,7 +29,7 @@ ClArgs::ClArgs(ox::SpanView args) noexcept { m_bools[arg] = false; } m_strings[arg] = val; - if (auto r = ox::atoi(val.c_str()); r.error == 0) { + if (auto r = ox::strToInt(val); r.error == 0) { m_ints[arg] = r.value; } ++i; diff --git a/deps/ox/src/ox/claw/read.cpp b/deps/ox/src/ox/claw/read.cpp index 91870b54..4d2e7f1e 100644 --- a/deps/ox/src/ox/claw/read.cpp +++ b/deps/ox/src/ox/claw/read.cpp @@ -81,7 +81,7 @@ Result readClawHeader(ox::BufferView buff) noexcept { return ox::Error(4, "Claw format does not match any supported format/version combo"); } hdr.typeName = typeName; - std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion); + std::ignore = ox::strToInt(versionStr).copyTo(hdr.typeVersion); hdr.data = buffRaw; hdr.dataSize = buffLen; return hdr; diff --git a/deps/ox/src/ox/fs/filesystem/filelocation.cpp b/deps/ox/src/ox/fs/filesystem/filelocation.cpp index b7c3b181..a7b9d71e 100644 --- a/deps/ox/src/ox/fs/filesystem/filelocation.cpp +++ b/deps/ox/src/ox/fs/filesystem/filelocation.cpp @@ -31,10 +31,10 @@ FileAddress::FileAddress(uint64_t inode) noexcept { FileAddress::FileAddress(ox::StringViewCR path) noexcept { auto pathSize = path.bytes(); m_data.path = new char[pathSize + 1]; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN memcpy(m_data.path, path.data(), pathSize); -OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) m_data.path[pathSize] = 0; -OX_CLANG_NOWARN_END + OX_ALLOW_UNSAFE_BUFFERS_END m_type = FileAddressType::Path; } @@ -48,9 +48,11 @@ FileAddress &FileAddress::operator=(const FileAddress &other) noexcept { case FileAddressType::Path: { if (other.m_data.path) { + OX_ALLOW_UNSAFE_BUFFERS_BEGIN auto strSize = ox::strlen(other.m_data.path) + 1; m_data.path = new char[strSize]; ox::memcpy(m_data.path, other.m_data.path, strSize); + OX_ALLOW_UNSAFE_BUFFERS_END } else { m_data.constPath = ""; m_type = FileAddressType::ConstPath; diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index bb706b9f..dfacd244 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -119,7 +119,9 @@ const std::map> tests = auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); ox::PathIterator it(path.c_str(), path.len()); auto buff = static_cast(ox_alloca(path.len() + 1)); + OX_ALLOW_UNSAFE_BUFFERS_BEGIN oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); + OX_ALLOW_UNSAFE_BUFFERS_END return ox::Error(0); } }, @@ -127,7 +129,9 @@ const std::map> tests = "PathIterator::hasNext", [](ox::StringView) { const auto path = "/file1"; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::PathIterator it(path, ox::strlen(path)); + OX_ALLOW_UNSAFE_BUFFERS_END oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext"); oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext"); return ox::Error(0); @@ -163,9 +167,11 @@ const std::map> tests = [](ox::StringView) { constexpr auto buffLen = 5000; constexpr auto str1 = "Hello, World!"; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN constexpr auto str1Len = ox::strlen(str1) + 1; constexpr auto str2 = "Hello, Moon!"; constexpr auto str2Len = ox::strlen(str2) + 1; + OX_ALLOW_UNSAFE_BUFFERS_END auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer>(buffLen); oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed."); ox::FileStore32 fileStore(list, buffLen); diff --git a/deps/ox/src/ox/fs/tool.cpp b/deps/ox/src/ox/fs/tool.cpp index da18878b..82992968 100644 --- a/deps/ox/src/ox/fs/tool.cpp +++ b/deps/ox/src/ox/fs/tool.cpp @@ -57,7 +57,9 @@ static ox::Error runRead(ox::FileSystem *fs, ox::Span args) noexcep return ox::Error(1); } OX_REQUIRE(buff, fs->read(ox::StringView(args[1]))); + OX_ALLOW_UNSAFE_BUFFERS_BEGIN std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout); + OX_ALLOW_UNSAFE_BUFFERS_END return ox::Error(0); } diff --git a/deps/ox/src/ox/mc/intops.hpp b/deps/ox/src/ox/mc/intops.hpp index fb087a98..5659311d 100644 --- a/deps/ox/src/ox/mc/intops.hpp +++ b/deps/ox/src/ox/mc/intops.hpp @@ -71,7 +71,9 @@ constexpr McInt encodeInteger(I pInput) noexcept { // move input to uint64_t to allow consistent bit manipulation, and to avoid // overflow concerns uint64_t val = 0; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::memcpy(&val, &input, sizeof(input)); + OX_ALLOW_UNSAFE_BUFFERS_END if (val) { // bits needed to represent number factoring in space possibly // needed for signed bit @@ -94,7 +96,9 @@ constexpr McInt encodeInteger(I pInput) noexcept { } if (bytes == 9) { out.data[0] = bytesIndicator; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::memcpy(&out.data[1], &leVal, 8); + OX_ALLOW_UNSAFE_BUFFERS_END if (inputNegative) { out.data[1] |= 0b1000'0000; } @@ -104,7 +108,9 @@ constexpr McInt encodeInteger(I pInput) noexcept { auto intermediate = static_cast(leVal.raw() | (negBit << (valBits - 1))) << bytes | static_cast(bytesIndicator); + OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate)); + OX_ALLOW_UNSAFE_BUFFERS_END } out.length = bytes; } @@ -151,33 +157,37 @@ constexpr Result decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe decoded >>= bytes; // move sign bit if constexpr(is_signed_v) { - const auto negBit = bytes * 8 - bytes - 1; - // move sign - const auto negative = (decoded >> negBit) == 1; - if (negative) { - // fill in all bits between encoded sign and real sign with 1s - // split it up because the 32-bit ARM can't shift more than 32 bits - ox::Array d = {}; - //d[0] = decoded & 0xffff'ffff; - //d[1] = decoded >> 32; - ox::memcpy(&d[0], &decoded, sizeof(decoded)); - auto bit = negBit; - for (; bit < ox::min(Bits, 32); ++bit) { - d[0] |= 1 << bit; - } - bit -= 32; - for (; bit < Bits; ++bit) { - d[1] |= 1 << bit; - } - I out = 0; - if constexpr(ox::defines::BigEndian) { - const auto d0Tmp = d[0]; - d[0] = d[1]; - d[1] = d0Tmp; - } - ox::memcpy(&out, &d[0], sizeof(out)); - return out; - } + const auto negBit = bytes * 8 - bytes - 1; + // move sign + const auto negative = (decoded >> negBit) == 1; + if (negative) { + // fill in all bits between encoded sign and real sign with 1s + // split it up because the 32-bit ARM can't shift more than 32 bits + ox::Array d = {}; + //d[0] = decoded & 0xffff'ffff; + //d[1] = decoded >> 32; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN + ox::memcpy(&d[0], &decoded, sizeof(decoded)); + OX_ALLOW_UNSAFE_BUFFERS_END + auto bit = negBit; + for (; bit < ox::min(Bits, 32); ++bit) { + d[0] |= 1 << bit; + } + bit -= 32; + for (; bit < Bits; ++bit) { + d[1] |= 1 << bit; + } + I out = 0; + if constexpr(ox::defines::BigEndian) { + const auto d0Tmp = d[0]; + d[0] = d[1]; + d[1] = d0Tmp; + } + OX_ALLOW_UNSAFE_BUFFERS_BEGIN + ox::memcpy(&out, &d[0], sizeof(out)); + OX_ALLOW_UNSAFE_BUFFERS_END + return out; + } } return static_cast(decoded); } diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index ba19e3f3..dfa70a2a 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -211,10 +211,12 @@ constexpr Error MetalClawWriter::field(const char *name, const IString -constexpr Error MetalClawWriter::fieldCString(const char*, const char *const*val, std::size_t) noexcept { +constexpr Error MetalClawWriter::fieldCString(const char*, const char *const*val, std::size_t buffLen) noexcept { bool fieldSet = false; if (!m_unionIdx.has_value() || *m_unionIdx == m_field) { - const auto strLen = *val ? ox::strlen(*val) : 0; + OX_ALLOW_UNSAFE_BUFFERS_BEGIN + const auto strLen = *val ? ox::strnlen_s(*val, buffLen) : 0; + OX_ALLOW_UNSAFE_BUFFERS_END // write the length const auto strLenBuff = mc::encodeInteger(strLen); OX_RETURN_ERROR(m_writer.write(reinterpret_cast(strLenBuff.data.data()), strLenBuff.length)); diff --git a/deps/ox/src/ox/model/modelvalue.hpp b/deps/ox/src/ox/model/modelvalue.hpp index 3031509c..030f648a 100644 --- a/deps/ox/src/ox/model/modelvalue.hpp +++ b/deps/ox/src/ox/model/modelvalue.hpp @@ -997,7 +997,7 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept { case Type::SignedInteger16: case Type::SignedInteger32: case Type::SignedInteger64: - ox::memcpy(&m_data, &other.m_data, sizeof(m_data)); + m_data = other.m_data; break; case Type::String: m_data.str = new String(other.get()); @@ -1030,8 +1030,8 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept { case Type::SignedInteger16: case Type::SignedInteger32: case Type::SignedInteger64: - ox::memcpy(&m_data, &other.m_data, sizeof(m_data)); - ox::memset(&other.m_data, 0, sizeof(m_data)); + m_data = other.m_data; + other.m_data.ui64 = 0; break; case Type::String: m_data.str = other.m_data.str; @@ -1223,7 +1223,7 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept { case Type::SignedInteger16: case Type::SignedInteger32: case Type::SignedInteger64: - ox::memcpy(&m_data, &other.m_data, sizeof(m_data)); + m_data = other.m_data; break; case Type::String: m_data.str = new String(other.get()); @@ -1261,8 +1261,8 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept { case Type::SignedInteger16: case Type::SignedInteger32: case Type::SignedInteger64: - ox::memcpy(&m_data, &other.m_data, sizeof(m_data)); - ox::memset(&other.m_data, 0, sizeof(m_data)); + m_data = other.m_data; + other.m_data = {}; break; case Type::String: m_data.str = other.m_data.str; diff --git a/deps/ox/src/ox/oc/read.cpp b/deps/ox/src/ox/oc/read.cpp index 2862e17e..a3a71e2e 100644 --- a/deps/ox/src/ox/oc/read.cpp +++ b/deps/ox/src/ox/oc/read.cpp @@ -15,7 +15,7 @@ namespace ox { OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) { auto json = reinterpret_cast(buff); - auto jsonLen = ox::strnlen(json, buffSize); + auto jsonLen = ox::strnlen_s(json, buffSize); Json::CharReaderBuilder parserBuilder; auto parser = std::unique_ptr(parserBuilder.newCharReader()); if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) { diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index 763e5102..bf449cd4 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -8,7 +8,11 @@ #pragma once +#include + +OX_ALLOW_UNSAFE_BUFFERS_BEGIN #include +OX_ALLOW_UNSAFE_BUFFERS_END #include #include diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index 2f956f44..37cbc6d0 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -8,7 +8,11 @@ #pragma once +#include + +OX_ALLOW_UNSAFE_BUFFERS_BEGIN #include +OX_ALLOW_UNSAFE_BUFFERS_END #include #include @@ -258,7 +262,9 @@ Result writeOC(const auto &val) noexcept { const auto str = Json::writeString(jsonBuilder, writer.m_json); Result buff; buff.value.resize(str.size() + 1); + OX_ALLOW_UNSAFE_BUFFERS_BEGIN memcpy(buff.value.data(), str.data(), str.size() + 1); + OX_ALLOW_UNSAFE_BUFFERS_END return buff; } @@ -270,7 +276,9 @@ Result writeOCString(const auto &val) noexcept { const auto str = Json::writeString(jsonBuilder, writer.m_json); Result buff; buff.value.resize(str.size()); + OX_ALLOW_UNSAFE_BUFFERS_BEGIN memcpy(buff.value.data(), str.data(), str.size() + 1); + OX_ALLOW_UNSAFE_BUFFERS_END return buff; } diff --git a/deps/ox/src/ox/std/cstrops.hpp b/deps/ox/src/ox/std/cstrops.hpp index 140a7956..a0686bb4 100644 --- a/deps/ox/src/ox/std/cstrops.hpp +++ b/deps/ox/src/ox/std/cstrops.hpp @@ -30,9 +30,12 @@ constexpr T1 strncpy(T1 dest, T2 src, std::size_t maxLen) noexcept { } [[nodiscard]] -constexpr auto strnlen(const char *str1, std::size_t maxLen) noexcept { - std::size_t len = 0; - for (; len < maxLen && str1[len]; len++); +constexpr size_t strnlen_s(const char *str, size_t const maxLen) noexcept { + if (!str) [[unlikely]] { + return 0; + } + size_t len = 0; + for (; len < maxLen && str[len]; len++); return len; } diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp index a0b7f993..7b83626f 100644 --- a/deps/ox/src/ox/std/span.hpp +++ b/deps/ox/src/ox/std/span.hpp @@ -8,6 +8,10 @@ #pragma once +#if __has_include() +#include +#endif + #include "array.hpp" #include "bit.hpp" #include "def.hpp" @@ -35,6 +39,20 @@ class Span { constexpr Span() noexcept = default; +#if __has_include() + template + constexpr Span(std::array &a) noexcept: + m_items(a.data()), + m_size(a.size()) { + } + + template + constexpr Span(std::array, sz> const&a) noexcept: + m_items(a.data()), + m_size(a.size()) { + } +#endif + template constexpr Span(ox::Array &a) noexcept: m_items(a.data()), diff --git a/deps/ox/src/ox/std/stringliteral.hpp b/deps/ox/src/ox/std/stringliteral.hpp index 7dbff8e4..a498075e 100644 --- a/deps/ox/src/ox/std/stringliteral.hpp +++ b/deps/ox/src/ox/std/stringliteral.hpp @@ -32,7 +32,9 @@ class StringLiteral: public detail::BaseStringView { constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {} + OX_ALLOW_UNSAFE_BUFFERS_BEGIN constexpr explicit StringLiteral(char const *str) noexcept: StringLiteral(str, ox::strlen(str)) {} + OX_ALLOW_UNSAFE_BUFFERS_END constexpr StringLiteral &operator=(StringLiteral const&other) noexcept { if (&other != this) { diff --git a/deps/ox/src/ox/std/stringview.hpp b/deps/ox/src/ox/std/stringview.hpp index ced0c905..eef1cc48 100644 --- a/deps/ox/src/ox/std/stringview.hpp +++ b/deps/ox/src/ox/std/stringview.hpp @@ -100,7 +100,8 @@ constexpr auto toStdStringView(StringViewCR sv) noexcept { #endif -constexpr ox::Result atoi(ox::StringViewCR str) noexcept { +constexpr ox::Result strToInt(ox::StringViewCR str) noexcept { + OX_ALLOW_UNSAFE_BUFFERS_BEGIN int total = 0; int multiplier = 1; for (auto i = static_cast(str.len()) - 1; i != -1; --i) { @@ -113,6 +114,7 @@ constexpr ox::Result atoi(ox::StringViewCR str) noexcept { } } return total; + OX_ALLOW_UNSAFE_BUFFERS_END } diff --git a/deps/ox/src/ox/std/strops.cpp b/deps/ox/src/ox/std/strops.cpp index c138b5e1..a6b7f756 100644 --- a/deps/ox/src/ox/std/strops.cpp +++ b/deps/ox/src/ox/std/strops.cpp @@ -9,6 +9,8 @@ #include "def.hpp" #include "strops.hpp" +OX_ALLOW_UNSAFE_BUFFERS_BEGIN + static_assert(ox::strcmp("asdf", "hijk") < 0, "asdf < hijk"); static_assert(ox::strcmp("hijk", "asdf") > 0, "hijk > asdf"); static_assert(ox::strcmp("resize", "read") > 0, "resize > read"); @@ -42,3 +44,5 @@ std::size_t strlen(const char *str) { } #endif + +OX_ALLOW_UNSAFE_BUFFERS_END \ No newline at end of file diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index d999d39d..77071999 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -145,6 +145,7 @@ OX_CLANG_NOWARN_END return ox::Error{}; } }, + OX_ALLOW_UNSAFE_BUFFERS_BEGIN { "ABCDEFG != HIJKLMN", []() { @@ -169,6 +170,7 @@ OX_CLANG_NOWARN_END return ox::Error(ox::memcmp("ABCDEFGHI", "ABCDEFG", 7) != 0); } }, + OX_ALLOW_UNSAFE_BUFFERS_END { "IString", []() { diff --git a/deps/ox/src/ox/std/tracehook.cpp b/deps/ox/src/ox/std/tracehook.cpp index 13b26db6..ec0ea743 100644 --- a/deps/ox/src/ox/std/tracehook.cpp +++ b/deps/ox/src/ox/std/tracehook.cpp @@ -39,6 +39,8 @@ enum LogChan { Debug = 4, }; +OX_ALLOW_UNSAFE_BUFFERS_BEGIN + template static void log(ox::StringViewCR str) { const auto sz = ox::min(0x100, str.bytes()); @@ -103,5 +105,7 @@ void oxTraceHook([[maybe_unused]] const char *file, [[maybe_unused]] int line, #endif } +OX_ALLOW_UNSAFE_BUFFERS_END + } diff --git a/deps/ox/src/ox/std/uuid.hpp b/deps/ox/src/ox/std/uuid.hpp index 60cd20a6..76bd1365 100644 --- a/deps/ox/src/ox/std/uuid.hpp +++ b/deps/ox/src/ox/std/uuid.hpp @@ -105,6 +105,10 @@ class UUID { ox::Array m_value{}; public: + + static constexpr auto TypeName = "net.drinkingtea.ox.UUID"; + static constexpr auto TypeVersion = 1; + static void seedGenerator(const RandomSeed &seed) noexcept; static ox::Result generate() noexcept;