From 5c2a33f23019260000d3bbfb2a0db0e606a11770 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Tue, 18 Jun 2024 14:22:12 +0200 Subject: [PATCH] Make stepfile schema validation more robust. (#5627) * Make stepfile schema validation more robust. * Update STEPFile.h --- code/AssetLib/IFC/IFCLoader.cpp | 9 ++++++++- code/AssetLib/Step/STEPFile.h | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/code/AssetLib/IFC/IFCLoader.cpp b/code/AssetLib/IFC/IFCLoader.cpp index 9414697df..13ea2d429 100644 --- a/code/AssetLib/IFC/IFCLoader.cpp +++ b/code/AssetLib/IFC/IFCLoader.cpp @@ -220,7 +220,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::unique_ptr db(STEP::ReadFileHeader(std::move(stream))); const STEP::HeaderInfo &head = static_cast(*db).GetHeader(); - if (!head.fileSchema.size() || head.fileSchema.substr(0, 3) != "IFC") { + if (!head.fileSchema.size() || head.fileSchema.substr(0, 4) != "IFC2") { ThrowException("Unrecognized file schema: " + head.fileSchema); } @@ -260,6 +260,8 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy ThrowException("missing IfcProject entity"); } + + ConversionData conv(*db, proj->To(), pScene, settings); SetUnits(conv); SetCoordinateSpace(conv); @@ -352,6 +354,11 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &co // ------------------------------------------------------------------------------------------------ void SetUnits(ConversionData &conv) { + if (conv.proj.UnitsInContext == nullptr) { + IFCImporter::LogError("Skipping conversion data, nullptr."); + return; + } + // see if we can determine the coordinate space used to express. for (size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i) { ConvertUnit(*conv.proj.UnitsInContext->Units[i], conv); diff --git a/code/AssetLib/Step/STEPFile.h b/code/AssetLib/Step/STEPFile.h index d8bc0ac49..1fd24b329 100644 --- a/code/AssetLib/Step/STEPFile.h +++ b/code/AssetLib/Step/STEPFile.h @@ -82,8 +82,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // this is intended as stress test - by default, entities are evaluated // lazily and therefore not unless needed. -//#define ASSIMP_IFC_TEST - namespace Assimp { // ******************************************************************************** @@ -531,6 +529,7 @@ public: template const T &To() const { + return dynamic_cast(**this); } @@ -581,12 +580,12 @@ private: }; template -inline bool operator==(const std::shared_ptr &lo, T whatever) { +inline bool operator == (const std::shared_ptr &lo, T whatever) { return *lo == whatever; // XXX use std::forward if we have 0x } template -inline bool operator==(const std::pair> &lo, T whatever) { +inline bool operator == (const std::pair> &lo, T whatever) { return *(lo.second) == whatever; // XXX use std::forward if we have 0x } @@ -599,18 +598,30 @@ struct Lazy { Lazy(const LazyObject *obj = nullptr) : obj(obj) {} operator const T *() const { + if (obj == nullptr) { + throw TypeError("Obj type is nullptr."); + } return obj->ToPtr(); } operator const T &() const { + if (obj == nullptr) { + throw TypeError("Obj type is nullptr."); + } return obj->To(); } const T &operator*() const { + if (obj == nullptr) { + throw TypeError("Obj type is nullptr."); + } return obj->To(); } const T *operator->() const { + if (obj == nullptr) { + throw TypeError("Obj type is nullptr."); + } return &obj->To(); }