From 0c6e47e0b3116b369d07aff594bba81a5b680d81 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 17 Feb 2022 02:50:14 -0600 Subject: [PATCH] [ox/claw] Fix Claw read to check for type/version compatibility --- deps/ox/src/ox/claw/read.hpp | 9 ++++++++ deps/ox/src/ox/model/typenamecatcher.hpp | 28 +++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/deps/ox/src/ox/claw/read.hpp b/deps/ox/src/ox/claw/read.hpp index 68951584..72728abf 100644 --- a/deps/ox/src/ox/claw/read.hpp +++ b/deps/ox/src/ox/claw/read.hpp @@ -19,6 +19,9 @@ namespace ox { +constexpr auto Error_ClawTypeMismatch = 200; +constexpr auto Error_ClawTypeVersionMismatch = 200; + struct ClawHeader { String typeName; int typeVersion = -1; @@ -38,6 +41,12 @@ Result stripClawHeader(const ox::Buffer &buff) noexcept; template Error readClaw(const char *buff, std::size_t buffLen, T *val) { oxRequire(header, readClawHeader(buff, buffLen)); + if (header.typeName != getModelTypeName()) { + return OxError(Error_ClawTypeMismatch, "Claw Read: Type mismatch"); + } + if (header.typeVersion != getModelTypeVersion()) { + return OxError(Error_ClawTypeVersionMismatch, "Claw Read: Type Verion mismatch"); + } switch (header.fmt) { case ClawFormat::Metal: { diff --git a/deps/ox/src/ox/model/typenamecatcher.hpp b/deps/ox/src/ox/model/typenamecatcher.hpp index 3a77917e..0635906f 100644 --- a/deps/ox/src/ox/model/typenamecatcher.hpp +++ b/deps/ox/src/ox/model/typenamecatcher.hpp @@ -20,12 +20,14 @@ namespace ox { struct TypeNameCatcher { const char *name = ""; + int version = 0; constexpr TypeNameCatcher() noexcept = default; template - constexpr void setTypeInfo(const char *n = T::TypeName, int = 0) noexcept { + constexpr void setTypeInfo(const char *n = T::TypeName, int v = 0) noexcept { this->name = n; + this->version = v; } template @@ -44,6 +46,30 @@ struct TypeNameCatcher { }; +template +constexpr int getModelTypeVersion() noexcept { + auto a = std::allocator(); + auto t = a.allocate(1); + TypeNameCatcher nc; + oxIgnoreError(model(&nc, t)); + a.deallocate(t, 1); + return nc.version; +} + +template +constexpr int getModelTypeVersion(T *val) noexcept { + TypeNameCatcher nc; + oxIgnoreError(model(&nc, val)); + return nc.version; +} + +template +consteval int requireModelTypeVersion() noexcept { + constexpr auto version = getModelTypeVersion(); + static_assert(version != 0, "TypeName is required"); + return version; +} + template constexpr Str getModelTypeName() noexcept { auto a = std::allocator();