From 24d110199a3c247f9b08f5faf738e4434225623d Mon Sep 17 00:00:00 2001 From: tanolino Date: Fri, 8 Jul 2022 10:19:50 +0200 Subject: [PATCH 1/2] Use size_t for file size instead of unsigned int This is one step to help us open files with more then 4 GB size. --- code/AssetLib/STL/STLLoader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssetLib/STL/STLLoader.h b/code/AssetLib/STL/STLLoader.h index a340abe6b..0be6a95f0 100644 --- a/code/AssetLib/STL/STLLoader.h +++ b/code/AssetLib/STL/STLLoader.h @@ -109,7 +109,7 @@ protected: const char* mBuffer; /** Size of the file, in bytes */ - unsigned int mFileSize; + size_t mFileSize; /** Output scene */ aiScene* mScene; From c23146bb20612ceaf19b5e2e7a8429bddd5b12f5 Mon Sep 17 00:00:00 2001 From: tanolino Date: Fri, 8 Jul 2022 10:26:03 +0200 Subject: [PATCH 2/2] Use size_t for the file size in cpp file This pointer juggling in combination with STL files >4GB caused some nasty illegal memory access bugs here. So let's fix it. --- code/AssetLib/STL/STLLoader.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/code/AssetLib/STL/STLLoader.cpp b/code/AssetLib/STL/STLLoader.cpp index 2087af850..cea448de1 100644 --- a/code/AssetLib/STL/STLLoader.cpp +++ b/code/AssetLib/STL/STLLoader.cpp @@ -73,7 +73,7 @@ static const aiImporterDesc desc = { // 1) 80 byte header // 2) 4 byte face count // 3) 50 bytes per face -static bool IsBinarySTL(const char *buffer, unsigned int fileSize) { +static bool IsBinarySTL(const char *buffer, size_t fileSize) { if (fileSize < 84) { return false; } @@ -92,7 +92,7 @@ static const char UnicodeBoundary = 127; // An ascii STL buffer will begin with "solid NAME", where NAME is optional. // Note: The "solid NAME" check is necessary, but not sufficient, to determine // if the buffer is ASCII; a binary header could also begin with "solid NAME". -static bool IsAsciiSTL(const char *buffer, unsigned int fileSize) { +static bool IsAsciiSTL(const char *buffer, size_t fileSize) { if (IsBinarySTL(buffer, fileSize)) return false; @@ -172,7 +172,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy throw DeadlyImportError("Failed to open STL file ", pFile, "."); } - mFileSize = (unsigned int)file->FileSize(); + mFileSize = file->FileSize(); // allocate storage and copy the contents of the file to a memory buffer // (terminate it with zero) @@ -233,7 +233,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) { // try to guess how many vertices we could have // assume we'll need 160 bytes for each face - size_t sizeEstimate = std::max(1u, mFileSize / 160u) * 3; + size_t sizeEstimate = std::max(1ull, mFileSize / 160ull) * 3ull; positionBuffer.reserve(sizeEstimate); normalBuffer.reserve(sizeEstimate); @@ -284,8 +284,6 @@ void STLImporter::LoadASCIIFile(aiNode *root) { ASSIMP_LOG_WARN("STL: A new facet begins but the old is not yet complete"); } faceVertexCounter = 0; - normalBuffer.push_back(aiVector3D()); - aiVector3D *vn = &normalBuffer.back(); sz += 6; SkipSpaces(&sz); @@ -295,15 +293,17 @@ void STLImporter::LoadASCIIFile(aiNode *root) { if (sz[6] == '\0') { throw DeadlyImportError("STL: unexpected EOF while parsing facet"); } + aiVector3D vn; sz += 7; SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->x); + sz = fast_atoreal_move(sz, (ai_real &)vn.x); SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->y); + sz = fast_atoreal_move(sz, (ai_real &)vn.y); SkipSpaces(&sz); - sz = fast_atoreal_move(sz, (ai_real &)vn->z); - normalBuffer.push_back(*vn); - normalBuffer.push_back(*vn); + sz = fast_atoreal_move(sz, (ai_real &)vn.z); + normalBuffer.emplace_back(vn); + normalBuffer.emplace_back(vn); + normalBuffer.emplace_back(vn); } } else if (!strncmp(sz, "vertex", 6) && ::IsSpaceOrNewLine(*(sz + 6))) { // vertex 1.50000 1.50000 0.00000 if (faceVertexCounter >= 3) { @@ -315,7 +315,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) { } sz += 7; SkipSpaces(&sz); - positionBuffer.push_back(aiVector3D()); + positionBuffer.emplace_back(); aiVector3D *vn = &positionBuffer.back(); sz = fast_atoreal_move(sz, (ai_real &)vn->x); SkipSpaces(&sz); @@ -439,7 +439,7 @@ bool STLImporter::LoadBinaryFile() { pMesh->mNumFaces = *((uint32_t *)sz); sz += 4; - if (mFileSize < 84 + pMesh->mNumFaces * 50) { + if (mFileSize < 84ull + pMesh->mNumFaces * 50ull) { throw DeadlyImportError("STL: file is too small to hold all facets"); }