Added a check to detect and prevent recursive references in GLTF2 files
parent
7e23773776
commit
1bc7c710d6
|
@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Exceptional.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
@ -82,14 +83,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||
# else
|
||||
# define gltf_unordered_map map
|
||||
# define gltf_unordered_set set
|
||||
#endif
|
||||
|
||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||
# include <unordered_map>
|
||||
# include <unordered_set>
|
||||
# if _MSC_VER > 1600
|
||||
# define gltf_unordered_map unordered_map
|
||||
# define gltf_unordered_set unordered_set
|
||||
# else
|
||||
# define gltf_unordered_map tr1::unordered_map
|
||||
# define gltf_unordered_set tr1::unordered_set
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -942,6 +947,8 @@ namespace glTF2
|
|||
Value* mDict; //! JSON dictionary object
|
||||
Asset& mAsset; //! The asset instance
|
||||
|
||||
std::gltf_unordered_set<unsigned int> mRecursiveReferenceCheck; //! Used by Retrieve to prevent recursive lookups
|
||||
|
||||
void AttachToDocument(Document& doc);
|
||||
void DetachFromDocument();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
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
|
||||
auto inst = std::unique_ptr<T>(new T());
|
||||
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);
|
||||
inst->Read(obj, mAsset);
|
||||
|
||||
return Add(inst.release());
|
||||
Ref<T> result = Add(inst.release());
|
||||
mRecursiveReferenceCheck.erase(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
|
Loading…
Reference in New Issue