diff --git a/.gitignore b/.gitignore index 55995220d..0ec07fc21 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ test/gtest/src/gtest-stamp/Debug/gtest-build *.lib test/gtest/src/gtest-stamp/Debug/ tools/assimp_view/assimp_viewer.vcxproj.user + +# Unix editor backups +*~ diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index 4f5614a00..6a51fb84f 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -175,6 +175,10 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile, // file. for (std::vector::iterator i = mScene->mMeshes.begin(), end = mScene->mMeshes.end(); i != end;++i) { + if ((*i).mFaces.size() > 0 && (*i).mPositions.size() == 0) { + delete mScene; + throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile); + } CheckIndices(*i); MakeUnique (*i); ComputeNormalsWithSmoothingsGroups(*i); @@ -944,6 +948,9 @@ void Discreet3DSImporter::ParseFaceChunk() // This is the list of smoothing groups - a bitfield for every face. // Up to 32 smoothing groups assigned to a single face. unsigned int num = chunkSize/4, m = 0; + if (num > mMesh.mFaces.size()) { + throw DeadlyImportError("3DS: More smoothing groups than faces"); + } for (std::vector::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) { // nth bit is set for nth smoothing group (*i).iSmoothGroup = stream->GetI4(); diff --git a/code/LWOBLoader.cpp b/code/LWOBLoader.cpp index cdbd9695f..6c9b0560a 100644 --- a/code/LWOBLoader.cpp +++ b/code/LWOBLoader.cpp @@ -139,7 +139,15 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face while (cursor < end && max--) { uint16_t numIndices; + // must have 2 shorts left for numIndices and surface + if (end - cursor < 2) { + throw DeadlyImportError("LWOB: Unexpected end of file"); + } ::memcpy(&numIndices, cursor++, 2); + // must have enough left for indices and surface + if (end - cursor < (1 + numIndices)) { + throw DeadlyImportError("LWOB: Unexpected end of file"); + } verts += numIndices; faces++; cursor += numIndices; diff --git a/code/LWOLoader.cpp b/code/LWOLoader.cpp index 14a9f261f..355e21298 100644 --- a/code/LWOLoader.cpp +++ b/code/LWOLoader.cpp @@ -730,6 +730,11 @@ void LWOImporter::LoadLWOPoints(unsigned int length) // --- this function is used for both LWO2 and LWOB but for // LWO2 we need to allocate 25% more storage - it could be we'll // need to duplicate some points later. + const size_t vertexLen = 12; + if ((length % vertexLen) != 0) + { + throw DeadlyImportError( "LWO2: Points chunk length is not multiple of vertexLen (12)"); + } register unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12; if (mIsLWO2) { diff --git a/code/OFFLoader.cpp b/code/OFFLoader.cpp index 23a1815c3..ca440a458 100644 --- a/code/OFFLoader.cpp +++ b/code/OFFLoader.cpp @@ -127,6 +127,13 @@ void OFFImporter::InternReadFile( const std::string& pFile, const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz); const unsigned int numFaces = strtoul10(sz,&sz); + if (!numVertices) { + throw DeadlyImportError("OFF: There are no valid vertices"); + } + if (!numFaces) { + throw DeadlyImportError("OFF: There are no valid faces"); + } + pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = 1 ]; aiMesh* mesh = pScene->mMeshes[0] = new aiMesh(); aiFace* faces = mesh->mFaces = new aiFace [mesh->mNumFaces = numFaces]; diff --git a/code/PlyLoader.cpp b/code/PlyLoader.cpp index 104e194d9..d61c4e5a7 100644 --- a/code/PlyLoader.cpp +++ b/code/PlyLoader.cpp @@ -156,7 +156,6 @@ void PLYImporter::InternReadFile( const std::string& pFile, } else { - delete[] this->mBuffer; AI_DEBUG_INVALIDATE_PTR(this->mBuffer); throw DeadlyImportError( "Invalid .ply file: Missing format specification"); } diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 068008d9e..6fedcd34a 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -229,6 +229,9 @@ void STLImporter::LoadASCIIFile() size_t temp; // setup the name of the node if ((temp = (size_t)(sz-szMe))) { + if (temp >= MAXLEN) { + throw DeadlyImportError( "STL: Node name too long" ); + } pScene->mRootNode->mName.length = temp; memcpy(pScene->mRootNode->mName.data,szMe,temp); diff --git a/code/XFileParser.cpp b/code/XFileParser.cpp index 36e70bc1c..a62aef414 100644 --- a/code/XFileParser.cpp +++ b/code/XFileParser.cpp @@ -214,6 +214,10 @@ XFileParser::XFileParser( const std::vector& pBuffer) AI_SWAP2(ofs); P += 4; + if (P + ofs > End + 2) { + throw DeadlyImportError("X: Unexpected EOF in compressed chunk"); + } + // push data to the stream stream.next_in = (Bytef*)P; stream.avail_in = ofs;