Cap glTFv1 & 2 json size to ~4GB
Ensures size_t cannot overflow Limits the maximum contiguous memory allocation to something plausible.pull/4160/head
parent
2b4b3e820b
commit
69cafe64b4
|
@ -1148,7 +1148,7 @@ inline void Asset::ReadBinaryHeader(IOStream &stream) {
|
||||||
AI_SWAP4(header.length);
|
AI_SWAP4(header.length);
|
||||||
AI_SWAP4(header.sceneLength);
|
AI_SWAP4(header.sceneLength);
|
||||||
|
|
||||||
mSceneLength = static_cast<size_t>(header.sceneLength);
|
mSceneLength = static_cast<size_t>(header.sceneLength); // Can't be larger than 4GB (max. uint32_t)
|
||||||
|
|
||||||
mBodyOffset = sizeof(header) + mSceneLength;
|
mBodyOffset = sizeof(header) + mSceneLength;
|
||||||
mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4
|
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;
|
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<uint32_t>::max()) {
|
||||||
|
throw DeadlyImportError("GLTF: JSON size greater than 4GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the scene data, ensure null termination
|
||||||
std::vector<char> sceneData(mSceneLength + 1);
|
std::vector<char> sceneData(mSceneLength + 1);
|
||||||
sceneData[mSceneLength] = '\0';
|
sceneData[mSceneLength] = '\0';
|
||||||
|
|
||||||
|
|
|
@ -1777,9 +1777,9 @@ inline void Asset::ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneDa
|
||||||
throw DeadlyImportError("GLTF: JSON chunk missing");
|
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.resize(mSceneLength + 1);
|
||||||
sceneData[mSceneLength] = '\0';
|
sceneData[mSceneLength] = '\0';
|
||||||
|
|
||||||
|
@ -1835,9 +1835,13 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
|
||||||
} else {
|
} else {
|
||||||
mSceneLength = stream->FileSize();
|
mSceneLength = stream->FileSize();
|
||||||
mBodyLength = 0;
|
mBodyLength = 0;
|
||||||
|
|
||||||
|
// Binary format only supports up to 4GB of JSON, use that as a maximum
|
||||||
|
if (mSceneLength > std::numeric_limits<uint32_t>::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.resize(mSceneLength + 1);
|
||||||
sceneData[mSceneLength] = '\0';
|
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
|
// parse the JSON document
|
||||||
ASSIMP_LOG_DEBUG("Parsing GLTF2 JSON");
|
ASSIMP_LOG_DEBUG("Parsing GLTF2 JSON");
|
||||||
Document doc;
|
Document doc;
|
||||||
|
|
Loading…
Reference in New Issue