Pārlūkot izejas kodu

Make stepfile schema validation more robust. (#5627)

* Make stepfile schema validation more robust.

* Update STEPFile.h
Kim Kulling 1 gadu atpakaļ
vecāks
revīzija
5c2a33f230
2 mainītis faili ar 23 papildinājumiem un 5 dzēšanām
  1. 8 1
      code/AssetLib/IFC/IFCLoader.cpp
  2. 15 4
      code/AssetLib/Step/STEPFile.h

+ 8 - 1
code/AssetLib/IFC/IFCLoader.cpp

@@ -220,7 +220,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(std::move(stream)));
     const STEP::HeaderInfo &head = static_cast<const STEP::DB &>(*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<Schema_2x3::IfcProject>(), 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);

+ 15 - 4
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 <typename T>
     const T &To() const {
+
         return dynamic_cast<const T &>(**this);
     }
 
@@ -581,12 +580,12 @@ private:
 };
 
 template <typename T>
-inline bool operator==(const std::shared_ptr<LazyObject> &lo, T whatever) {
+inline bool operator == (const std::shared_ptr<LazyObject> &lo, T whatever) {
     return *lo == whatever; // XXX use std::forward if we have 0x
 }
 
 template <typename T>
-inline bool operator==(const std::pair<uint64_t, std::shared_ptr<LazyObject>> &lo, T whatever) {
+inline bool operator == (const std::pair<uint64_t, std::shared_ptr<LazyObject>> &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<T>();
     }
 
     operator const T &() const {
+        if (obj == nullptr) {
+            throw TypeError("Obj type is nullptr.");
+        }
         return obj->To<T>();
     }
 
     const T &operator*() const {
+        if (obj == nullptr) {
+            throw TypeError("Obj type is nullptr.");
+        }
         return obj->To<T>();
     }
 
     const T *operator->() const {
+        if (obj == nullptr) {
+            throw TypeError("Obj type is nullptr.");
+        }
         return &obj->To<T>();
     }