From d767d27ca89ee73f12e27f88a464455cedac4e0a Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 18 Sep 2023 21:40:13 +0200 Subject: [PATCH] CXMeshFileLoader: revise error checking Even when an error was encountered ::load() would still attempt to assemble the mesh, this was a pretty big problem. --- source/Irrlicht/CXMeshFileLoader.cpp | 127 +++++++++++++++++---------- source/Irrlicht/CXMeshFileLoader.h | 2 + 2 files changed, 82 insertions(+), 47 deletions(-) diff --git a/source/Irrlicht/CXMeshFileLoader.cpp b/source/Irrlicht/CXMeshFileLoader.cpp index 108ce179..95eaaf26 100644 --- a/source/Irrlicht/CXMeshFileLoader.cpp +++ b/source/Irrlicht/CXMeshFileLoader.cpp @@ -17,6 +17,8 @@ #endif //#define BETTER_MESHBUFFER_SPLITTING_FOR_X +#define SET_ERR_AND_RETURN() do { ErrorState = true; return false; } while (0) + namespace irr { namespace scene @@ -24,7 +26,7 @@ namespace scene //! Constructor CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr) -: AnimatedMesh(0), Buffer(0), P(0), End(0), BinaryNumCount(0), Line(0), +: AnimatedMesh(0), Buffer(0), P(0), End(0), BinaryNumCount(0), Line(0), ErrorState(false), CurFrame(0), MajorVersion(0), MinorVersion(0), BinaryFormat(false), FloatSize(0) { #ifdef _DEBUG @@ -466,7 +468,7 @@ bool CXMeshFileLoader::parseFile() // loop } - return true; + return !ErrorState; } @@ -545,7 +547,7 @@ bool CXMeshFileLoader::parseDataObjectTemplate() os::Printer::log("Left delimiter in template data object missing.", name.c_str(), ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read GUID @@ -587,7 +589,7 @@ bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent) { os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } CSkinnedMesh::SJoint *joint=0; @@ -638,7 +640,7 @@ bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent) { os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } else if (objectName == "}") @@ -701,7 +703,7 @@ bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat) { os::Printer::log("No opening brace in Transformation Matrix found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } readMatrix(mat); @@ -716,7 +718,7 @@ bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat) { os::Printer::log("No closing brace in Transformation Matrix found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; @@ -734,7 +736,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) #endif os::Printer::log("No opening brace in Mesh found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } #ifdef _XREADER_DEBUG @@ -778,7 +780,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) { os::Printer::log("Invalid face count (<3) found in Mesh x file reader.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read face indices @@ -808,6 +810,15 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) } } + for (u32 j = 0; j < mesh.Indices.size(); j++) + { + if (mesh.Indices[j] >= mesh.Vertices.size()) + { + os::Printer::log("Out of range index found in Mesh x file reader.", ELL_WARNING); + SET_ERR_AND_RETURN(); + } + } + if (!checkForTwoFollowingSemicolons()) { os::Printer::log("No finishing semicolon in Mesh Face Array found in x file", ELL_WARNING); @@ -824,7 +835,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) { os::Printer::log("Unexpected ending found in Mesh in x file.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } else if (objectName == "}") @@ -874,7 +885,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) { os::Printer::log("No starting brace in DeclData found.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // arbitrary vertex attributes // first comes the number of element definitions @@ -1005,7 +1016,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) os::Printer::log("No closing brace in DeclData.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); delete [] data; - return false; + SET_ERR_AND_RETURN(); } u8* dataptr = (u8*) data; if ((uv2pos != -1) && (uv2type == 1)) @@ -1029,7 +1040,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) { os::Printer::log("No starting brace in FVFData found.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } const u32 dataformat = readInt(); const u32 datasize = readInt(); @@ -1057,7 +1068,7 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) { os::Printer::log("No closing brace in FVFData found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } } else @@ -1096,7 +1107,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) { os::Printer::log("No opening brace in Skin Weights found in .x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } core::stringc TransformNodeName; @@ -1105,7 +1116,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) { os::Printer::log("Unknown syntax while reading transform node name string in .x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } mesh.HasSkinning=true; @@ -1179,7 +1190,7 @@ bool CXMeshFileLoader::parseDataObjectSkinWeights(SXMesh &mesh) { os::Printer::log("No closing brace in Skin Weights found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; @@ -1196,7 +1207,7 @@ bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh) { os::Printer::log("No opening brace in Skin Mesh header found in .x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } mesh.MaxSkinWeightsPerVertex = readInt(); @@ -1210,7 +1221,7 @@ bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh) { os::Printer::log("No closing brace in skin mesh header in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; @@ -1227,7 +1238,7 @@ bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) { os::Printer::log("No opening brace in Mesh Normals found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read count @@ -1250,6 +1261,13 @@ bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) // read face normal indices const u32 nFNormals = readInt(); + //if (nFNormals >= mesh.IndexCountPerFace.size()) + if (0) // this condition doesn't work for some reason + { + os::Printer::log("Too many face normals found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + SET_ERR_AND_RETURN(); + } u32 normalidx = 0; core::array polygonfaces; @@ -1263,7 +1281,7 @@ bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) { os::Printer::log("Not matching normal and face index count found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } if (indexcount == 3) @@ -1301,7 +1319,7 @@ bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) { os::Printer::log("No closing brace in Mesh Normals found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; @@ -1318,10 +1336,18 @@ bool CXMeshFileLoader::parseDataObjectMeshTextureCoords(SXMesh &mesh) { os::Printer::log("No opening brace in Mesh Texture Coordinates found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } const u32 nCoords = readInt(); + //if (nCoords >= mesh.Vertices.size()) + if (0) // this condition doesn't work for some reason + { + os::Printer::log("Too many texture coords found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + SET_ERR_AND_RETURN(); + } + for (u32 i=0; i= core::max_(nMaterials, 1U)) + { + os::Printer::log("Out of range index found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + SET_ERR_AND_RETURN(); + } const u32 fc = mesh.IndexCountPerFace[tfi]/3; for (u32 k=0; ksetAnimationSpeed(static_cast(ticks)); @@ -1572,7 +1605,7 @@ bool CXMeshFileLoader::parseDataObjectAnimation() { os::Printer::log("No opening brace in Animation found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } //anim.closed = true; @@ -1589,7 +1622,7 @@ bool CXMeshFileLoader::parseDataObjectAnimation() { os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } else if (objectName == "}") @@ -1619,14 +1652,14 @@ bool CXMeshFileLoader::parseDataObjectAnimation() { os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } } else { os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING); if (!parseUnknownDataObject()) - return false; + SET_ERR_AND_RETURN(); } } @@ -1691,7 +1724,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("No opening brace in Animation Key found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read key type @@ -1702,7 +1735,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("Unknown key type found in Animation Key in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read number of keys @@ -1730,7 +1763,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("Expected 4 numbers in animation key in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } f32 W = -readFloat(); @@ -1760,7 +1793,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("Expected 3 numbers in animation key in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } core::vector3df vector; @@ -1796,7 +1829,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("Expected 16 numbers in animation key in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } // read matrix @@ -1849,7 +1882,7 @@ bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) { os::Printer::log("No closing brace in animation key in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; @@ -1866,21 +1899,21 @@ bool CXMeshFileLoader::parseDataObjectTextureFilename(core::stringc& texturename { os::Printer::log("No opening brace in Texture filename found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } if (!getNextTokenAsString(texturename)) { os::Printer::log("Unknown syntax while reading texture filename string in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } if (!checkForClosingBrace()) { os::Printer::log("No closing brace in Texture filename found in x file", ELL_WARNING); os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); - return false; + SET_ERR_AND_RETURN(); } return true; diff --git a/source/Irrlicht/CXMeshFileLoader.h b/source/Irrlicht/CXMeshFileLoader.h index d4a85fac..8308b7cc 100644 --- a/source/Irrlicht/CXMeshFileLoader.h +++ b/source/Irrlicht/CXMeshFileLoader.h @@ -167,6 +167,8 @@ private: u32 Line; io::path FilePath; + bool ErrorState; + CSkinnedMesh::SJoint *CurFrame; core::array Meshes;