Added a check to detect and prevent recursive references in GLTF2 files

pull/3070/head
Max Vollmer 2020-03-11 09:54:24 +00:00
parent 7e23773776
commit 1bc7c710d6
2 changed files with 15 additions and 1 deletions

View File

@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
@ -82,14 +83,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP # define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# else # else
# define gltf_unordered_map map # define gltf_unordered_map map
# define gltf_unordered_set set
#endif #endif
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP #ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# include <unordered_map> # include <unordered_map>
# include <unordered_set>
# if _MSC_VER > 1600 # if _MSC_VER > 1600
# define gltf_unordered_map unordered_map # define gltf_unordered_map unordered_map
# define gltf_unordered_set unordered_set
# else # else
# define gltf_unordered_map tr1::unordered_map # define gltf_unordered_map tr1::unordered_map
# define gltf_unordered_set tr1::unordered_set
# endif # endif
#endif #endif
@ -942,6 +947,8 @@ namespace glTF2
Value* mDict; //! JSON dictionary object Value* mDict; //! JSON dictionary object
Asset& mAsset; //! The asset instance Asset& mAsset; //! The asset instance
std::gltf_unordered_set<unsigned int> mRecursiveReferenceCheck; //! Used by Retrieve to prevent recursive lookups
void AttachToDocument(Document& doc); void AttachToDocument(Document& doc);
void DetachFromDocument(); void DetachFromDocument();

View File

@ -270,6 +270,11 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object"); throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
} }
if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" has recursive reference to itself");
}
mRecursiveReferenceCheck.insert(i);
// Unique ptr prevents memory leak in case of Read throws an exception // Unique ptr prevents memory leak in case of Read throws an exception
auto inst = std::unique_ptr<T>(new T()); auto inst = std::unique_ptr<T>(new T());
inst->id = std::string(mDictId) + "_" + to_string(i); inst->id = std::string(mDictId) + "_" + to_string(i);
@ -277,7 +282,9 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
ReadMember(obj, "name", inst->name); ReadMember(obj, "name", inst->name);
inst->Read(obj, mAsset); inst->Read(obj, mAsset);
return Add(inst.release()); Ref<T> result = Add(inst.release());
mRecursiveReferenceCheck.erase(i);
return result;
} }
template<class T> template<class T>