diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp index 1fb9490cc..6b820d046 100644 --- a/code/AssetLib/DXF/DXFLoader.cpp +++ b/code/AssetLib/DXF/DXFLoader.cpp @@ -71,7 +71,7 @@ static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f)); // color indices for DXF - 16 are supported, the table is // taken directly from the DXF spec. static aiColor4D g_aclrDxfIndexColors[] = { - aiColor4D (0.6f, 0.6f, 0.6f, 1.0f), + aiColor4D(0.6f, 0.6f, 0.6f, 1.0f), aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue @@ -88,6 +88,7 @@ static aiColor4D g_aclrDxfIndexColors[] = { aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet }; + #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0])) #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC" @@ -109,14 +110,6 @@ static const aiImporterDesc desc = { "dxf" }; -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -DXFImporter::DXFImporter() = default; - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -DXFImporter::~DXFImporter() = default; - // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const { @@ -229,7 +222,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) { ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); } - if (! output.blocks.size() ) { + if (output.blocks.empty()) { throw DeadlyImportError("DXF: no data blocks loaded"); } @@ -587,10 +580,11 @@ void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) } } -#define DXF_POLYLINE_FLAG_CLOSED 0x1 -#define DXF_POLYLINE_FLAG_3D_POLYLINE 0x8 -#define DXF_POLYLINE_FLAG_3D_POLYMESH 0x10 -#define DXF_POLYLINE_FLAG_POLYFACEMESH 0x40 +static constexpr unsigned int DXF_POLYLINE_FLAG_CLOSED = 0x1; +// Currently unused +//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYLINE = 0x8; +//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYMESH = 0x10; +static constexpr unsigned int DXF_POLYLINE_FLAG_POLYFACEMESH = 0x40; // ------------------------------------------------------------------------------------------------ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) { @@ -639,12 +633,6 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) reader++; } - //if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH)) { - // DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags)); - // output.blocks.back().lines.pop_back(); - // return; - //} - if (vguess && line.positions.size() != vguess) { ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ", line.positions.size(),", expected ", vguess ); @@ -734,12 +722,18 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li case 71: case 72: case 73: - case 74: - if (cnti == 4) { - ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring"); - break; + case 74: { + if (cnti == 4) { + ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring"); + break; + } + const int index = reader.ValueAsSignedInt(); + if (index >= 0) { + indices[cnti++] = static_cast(index); + } else { + ASSIMP_LOG_WARN("DXF: Skip invisible face."); + } } - indices[cnti++] = reader.ValueAsUnsignedInt(); break; // color @@ -777,8 +771,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li } // ------------------------------------------------------------------------------------------------ -void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) -{ +void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) { // (note) this is also used for for parsing line entities, so we // must handle the vertex_count == 2 case as well. @@ -795,8 +788,7 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) if (reader.GroupCode() == 0) { break; } - switch (reader.GroupCode()) - { + switch (reader.GroupCode()) { // 8 specifies the layer case 8: diff --git a/code/AssetLib/DXF/DXFLoader.h b/code/AssetLib/DXF/DXFLoader.h index b32ae106f..89a0b79c2 100644 --- a/code/AssetLib/DXF/DXFLoader.h +++ b/code/AssetLib/DXF/DXFLoader.h @@ -68,8 +68,8 @@ namespace DXF { */ class DXFImporter : public BaseImporter { public: - DXFImporter(); - ~DXFImporter() override; + DXFImporter() = default; + ~DXFImporter() override = default; // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. diff --git a/code/AssetLib/OFF/OFFLoader.cpp b/code/AssetLib/OFF/OFFLoader.cpp index cb265029a..f50afb57b 100644 --- a/code/AssetLib/OFF/OFFLoader.cpp +++ b/code/AssetLib/OFF/OFFLoader.cpp @@ -284,7 +284,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS for (unsigned int i = 0; i < numFaces; ) { if(!GetNextLine(buffer,line)) { ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect"); - break; + throw DeadlyImportError("OFF: The number of faces in the header is incorrect"); } unsigned int idx; sz = line; SkipSpaces(&sz); diff --git a/code/AssetLib/Obj/ObjFileParser.cpp b/code/AssetLib/Obj/ObjFileParser.cpp index ed416dc93..ad97a470b 100644 --- a/code/AssetLib/Obj/ObjFileParser.cpp +++ b/code/AssetLib/Obj/ObjFileParser.cpp @@ -456,8 +456,19 @@ void ObjFileParser::getFace(aiPrimitiveType type) { iPos = 0; } else { //OBJ USES 1 Base ARRAYS!!!! - const char *token = &(*m_DataIt); - const int iVal = ::atoi(token); + int iVal; + auto end = m_DataIt; + // find either the buffer end or the '\0' + while (end < m_DataItEnd && *end != '\0') + ++end; + // avoid temporary string allocation if there is a zero + if (end != m_DataItEnd) { + iVal = ::atoi(&(*m_DataIt)); + } else { + // otherwise make a zero terminated copy, which is safe to pass to atoi + std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt); + iVal = ::atoi(number.c_str()); + } // increment iStep position based off of the sign and # of digits int tmp = iVal; diff --git a/code/Common/FileSystemFilter.h b/code/Common/FileSystemFilter.h index d28233ae9..c530153d4 100644 --- a/code/Common/FileSystemFilter.h +++ b/code/Common/FileSystemFilter.h @@ -297,7 +297,7 @@ private: } const char separator = getOsSeparator(); - for (it = in.begin(); it != in.end(); ++it) { + for (it = in.begin(); it < in.end(); ++it) { const size_t remaining = std::distance(in.end(), it); // Exclude :// and \\, which remain untouched. // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 diff --git a/code/PostProcessing/FindInvalidDataProcess.cpp b/code/PostProcessing/FindInvalidDataProcess.cpp index bb8e365a1..aa91139bc 100644 --- a/code/PostProcessing/FindInvalidDataProcess.cpp +++ b/code/PostProcessing/FindInvalidDataProcess.cpp @@ -82,6 +82,9 @@ void UpdateMeshReferences(aiNode *node, const std::vector &meshMap for (unsigned int a = 0; a < node->mNumMeshes; ++a) { unsigned int ref = node->mMeshes[a]; + if (ref >= meshMapping.size()) + throw DeadlyImportError("Invalid mesh ref"); + if (UINT_MAX != (ref = meshMapping[ref])) { node->mMeshes[out++] = ref; } @@ -143,7 +146,13 @@ void FindInvalidDataProcess::Execute(aiScene *pScene) { // we need to remove some meshes. // therefore we'll also need to remove all references // to them from the scenegraph - UpdateMeshReferences(pScene->mRootNode, meshMapping); + try { + UpdateMeshReferences(pScene->mRootNode, meshMapping); + } catch (const std::exception&) { + // fix the real number of meshes otherwise we'll get double free in the scene destructor + pScene->mNumMeshes = real; + throw; + } pScene->mNumMeshes = real; } diff --git a/contrib/poly2tri_patch.txt b/contrib/poly2tri_patch.txt deleted file mode 100644 index e9cca4cec..000000000 --- a/contrib/poly2tri_patch.txt +++ /dev/null @@ -1,75 +0,0 @@ -diff -r 5de9623d6a50 poly2tri/common/shapes.h ---- a/poly2tri/common/shapes.h Mon Aug 08 22:26:41 2011 -0400 -+++ b/poly2tri/common/shapes.h Tue Jan 17 02:36:52 2012 +0100 -@@ -35,6 +35,7 @@ - - #include - #include -+#include - #include - #include - -@@ -136,7 +137,9 @@ - p = &p2; - } else if (p1.x == p2.x) { - // Repeat points -- assert(false); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("repeat points"); -+ //assert(false); - } - } - -diff -r 5de9623d6a50 poly2tri/sweep/sweep.cc ---- a/poly2tri/sweep/sweep.cc Mon Aug 08 22:26:41 2011 -0400 -+++ b/poly2tri/sweep/sweep.cc Tue Jan 17 02:36:52 2012 +0100 -@@ -113,6 +113,8 @@ - Point* p1 = triangle->PointCCW(point); - Orientation o1 = Orient2d(eq, *p1, ep); - if (o1 == COLLINEAR) { -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); - if( triangle->Contains(&eq, p1)) { - triangle->MarkConstrainedEdge(&eq, p1 ); - // We are modifying the constraint maybe it would be better to -@@ -121,8 +123,8 @@ - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p1, triangle, *p1 ); - } else { -+ // ASSIMP_CHANGE (aramis_acg) - std::runtime_error("EdgeEvent - collinear points not supported"); -- assert(0); - } - return; - } -@@ -130,6 +132,9 @@ - Point* p2 = triangle->PointCW(point); - Orientation o2 = Orient2d(eq, *p2, ep); - if (o2 == COLLINEAR) { -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); -+ - if( triangle->Contains(&eq, p2)) { - triangle->MarkConstrainedEdge(&eq, p2 ); - // We are modifying the constraint maybe it would be better to -@@ -138,8 +143,8 @@ - triangle = &triangle->NeighborAcross(point); - EdgeEvent( tcx, ep, *p2, triangle, *p2 ); - } else { -- std::runtime_error("EdgeEvent - collinear points not supported"); -- assert(0); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("EdgeEvent - collinear points not supported"); - } - return; - } -@@ -712,7 +717,8 @@ - return *ot.PointCW(op); - } else{ - //throw new RuntimeException("[Unsupported] Opposing point on constrained edge"); -- assert(0); -+ // ASSIMP_CHANGE (aramis_acg) -+ throw std::runtime_error("[Unsupported] Opposing point on constrained edge"); - } - } - diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt index 5bc2d6065..af8aa4f65 100644 --- a/contrib/zlib/CMakeLists.txt +++ b/contrib/zlib/CMakeLists.txt @@ -76,15 +76,7 @@ if(MSVC) set(CMAKE_DEBUG_POSTFIX "d") add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype") - endif() - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -else() - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype") - endif() endif() if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)