diff --git a/code/AssetLib/glTF/glTFAsset.inl b/code/AssetLib/glTF/glTFAsset.inl index 387fd27df..353dd5aab 100644 --- a/code/AssetLib/glTF/glTFAsset.inl +++ b/code/AssetLib/glTF/glTFAsset.inl @@ -1148,7 +1148,7 @@ inline void Asset::ReadBinaryHeader(IOStream &stream) { AI_SWAP4(header.length); AI_SWAP4(header.sceneLength); - mSceneLength = static_cast(header.sceneLength); + mSceneLength = static_cast(header.sceneLength); // Can't be larger than 4GB (max. uint32_t) mBodyOffset = sizeof(header) + mSceneLength; mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4 @@ -1179,8 +1179,17 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) { mBodyLength = 0; } - // read the scene data + // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later + if (mSceneLength < 2) { + throw DeadlyImportError("GLTF: No JSON file contents"); + } + // Binary format only supports up to 4GB of JSON so limit it there to avoid extreme memory allocation + if (mSceneLength > std::numeric_limits::max()) { + throw DeadlyImportError("GLTF: JSON size greater than 4GB"); + } + + // read the scene data, ensure null termination std::vector sceneData(mSceneLength + 1); sceneData[mSceneLength] = '\0'; diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl index d65b4132b..d9d783e47 100644 --- a/code/AssetLib/glTF2/glTF2Asset.inl +++ b/code/AssetLib/glTF2/glTF2Asset.inl @@ -1777,9 +1777,9 @@ inline void Asset::ReadBinaryHeader(IOStream &stream, std::vector &sceneDa throw DeadlyImportError("GLTF: JSON chunk missing"); } - // read the scene data + // read the scene data, ensure null termination - mSceneLength = chunk.chunkLength; + mSceneLength = chunk.chunkLength; // Can't be larger than 4GB (max. uint32_t) sceneData.resize(mSceneLength + 1); sceneData[mSceneLength] = '\0'; @@ -1835,9 +1835,13 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) { } else { mSceneLength = stream->FileSize(); mBodyLength = 0; + + // Binary format only supports up to 4GB of JSON, use that as a maximum + if (mSceneLength > std::numeric_limits::max()) { + throw DeadlyImportError("GLTF: JSON size greater than 4GB"); + } - // read the scene data - + // read the scene data, ensure null termination sceneData.resize(mSceneLength + 1); sceneData[mSceneLength] = '\0'; @@ -1846,6 +1850,11 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) { } } + // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later + if (mSceneLength < 2) { + throw DeadlyImportError("GLTF: No JSON file contents"); + } + // parse the JSON document ASSIMP_LOG_DEBUG("Parsing GLTF2 JSON"); Document doc;