From edaf87f186bea8d43225ab1d6b61a6c2fa4863aa Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 30 Aug 2024 19:29:32 +0200 Subject: [PATCH 01/10] Update ccpp.yml (#5740) - Add ccache to build --- .github/workflows/ccpp.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index b6cfae367..d17faa114 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -37,6 +37,9 @@ jobs: cc: gcc steps: + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + - uses: actions/checkout@v4 with: submodules: true From 1e09642382ef914c5178cedbbf86ac4a9b982a48 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 30 Aug 2024 19:43:39 +0200 Subject: [PATCH 02/10] Ply-Importer: Fix vulnerability (#5739) --- code/AssetLib/Ply/PlyLoader.cpp | 3 +++ test/models/PLY/payload_JVN42386607 | 31 +++++++++++++++++++++++++++++ test/unit/utPLYImportExport.cpp | 6 ++++++ 3 files changed, 40 insertions(+) create mode 100644 test/models/PLY/payload_JVN42386607 diff --git a/code/AssetLib/Ply/PlyLoader.cpp b/code/AssetLib/Ply/PlyLoader.cpp index b211818df..5b3d3a699 100644 --- a/code/AssetLib/Ply/PlyLoader.cpp +++ b/code/AssetLib/Ply/PlyLoader.cpp @@ -448,6 +448,9 @@ void PLYImporter::LoadVertex(const PLY::Element *pcElement, const PLY::ElementIn mGeneratedMesh->mNumVertices = pcElement->NumOccur; mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices]; } + if (pos >= mGeneratedMesh->mNumVertices) { + throw DeadlyImportError("Invalid .ply file: Too many vertices"); + } mGeneratedMesh->mVertices[pos] = vOut; diff --git a/test/models/PLY/payload_JVN42386607 b/test/models/PLY/payload_JVN42386607 new file mode 100644 index 000000000..e372bf324 --- /dev/null +++ b/test/models/PLY/payload_JVN42386607 @@ -0,0 +1,31 @@ +ply +format ascii +element vertex 7 +property int x +property int nx +element vertex 9 +property float x +property float y +property float z +element face 3 +property list int8 int vertex_index +end_header +8 8 +8 8 +8 8 +8 8 +8 8 +8 8 +8 8 +9 9 9 +9 9 9 +9 9 9 +9 9 9 +9 9 9 +9 9 9 +9 9 9 +0 2.4902982818549262e-43 0 +-3.418291644037699e+33 4.591734678053128e-41 0 +42 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +42 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 4143600380 32767 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/test/unit/utPLYImportExport.cpp b/test/unit/utPLYImportExport.cpp index e748a40cf..54d7e4328 100644 --- a/test/unit/utPLYImportExport.cpp +++ b/test/unit/utPLYImportExport.cpp @@ -203,3 +203,9 @@ TEST_F(utPLYImportExport, parseInvalid) { const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/invalid/crash-30d6d0f7c529b3b66b4131700b7a4580cd7082df.ply", 0); EXPECT_EQ(nullptr, scene); } + +TEST_F(utPLYImportExport, payload_JVN42386607) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/payload_JVN42386607", 0); + EXPECT_EQ(nullptr, scene); +} \ No newline at end of file From c35200e38ea8f058812b83de2ef32c6093b0ece2 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 30 Aug 2024 20:35:01 +0200 Subject: [PATCH 03/10] prepare v5.4.3 (#5741) * prepare v5.4.3 - Increase patch level * Update utVersion.cpp Fix version test --- CMakeLists.txt | 2 +- test/unit/utVersion.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 074d64839..d45eb2253 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ IF(ASSIMP_HUNTER_ENABLED) add_definitions(-DASSIMP_USE_HUNTER) ENDIF() -PROJECT(Assimp VERSION 5.4.1) +PROJECT(Assimp VERSION 5.4.3) # All supported options ############################################### diff --git a/test/unit/utVersion.cpp b/test/unit/utVersion.cpp index 237382afc..57a3a57db 100644 --- a/test/unit/utVersion.cpp +++ b/test/unit/utVersion.cpp @@ -61,7 +61,7 @@ TEST_F( utVersion, aiGetVersionMinorTest ) { } TEST_F( utVersion, aiGetVersionPatchTest ) { - EXPECT_EQ(aiGetVersionPatch(), 1U ); + EXPECT_EQ(aiGetVersionPatch(), 3U ); } TEST_F( utVersion, aiGetCompileFlagsTest ) { From c1ffbfec06aa27fd6909d3f2b011a73d8d7a2d0d Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Tue, 3 Sep 2024 09:26:27 +0100 Subject: [PATCH 04/10] Zero-length mChildren arrays should be nullptr (#5749) - Children: Don't allocate a zero-length array - aiNode::mChildren should be left nullptr instead. --- code/AssetLib/3DS/3DSConverter.cpp | 10 ++++++++-- code/AssetLib/COB/COBLoader.cpp | 8 +++++--- code/AssetLib/FBX/FBXConverter.cpp | 12 ++++++------ code/AssetLib/SMD/SMDLoader.cpp | 6 +++++- code/PostProcessing/ValidateDataStructure.cpp | 3 +++ 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/code/AssetLib/3DS/3DSConverter.cpp b/code/AssetLib/3DS/3DSConverter.cpp index 7d1c24cd6..50600ba10 100644 --- a/code/AssetLib/3DS/3DSConverter.cpp +++ b/code/AssetLib/3DS/3DSConverter.cpp @@ -643,11 +643,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, } // Allocate storage for children - pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size(); + const unsigned int size = static_cast(pcIn->mChildren.size()); + + pcOut->mNumChildren = size; + if (size == 0) { + return; + } + pcOut->mChildren = new aiNode *[pcIn->mChildren.size()]; // Recursively process all children - const unsigned int size = static_cast(pcIn->mChildren.size()); + for (unsigned int i = 0; i < size; ++i) { pcOut->mChildren[i] = new aiNode(); pcOut->mChildren[i]->mParent = pcOut; diff --git a/code/AssetLib/COB/COBLoader.cpp b/code/AssetLib/COB/COBLoader.cpp index f0899bddd..6c85edfc9 100644 --- a/code/AssetLib/COB/COBLoader.cpp +++ b/code/AssetLib/COB/COBLoader.cpp @@ -372,9 +372,11 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi } // add children recursively - nd->mChildren = new aiNode *[root.temp_children.size()](); - for (const Node *n : root.temp_children) { - (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd; + if (!root.temp_children.empty()) { + nd->mChildren = new aiNode *[root.temp_children.size()](); + for (const Node *n : root.temp_children) { + (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd; + } } return nd; diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index fd54c63f4..d9718685d 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -357,12 +357,12 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) if (nodes.empty()) { parent->mNumChildren = 0; parent->mChildren = nullptr; - } - - parent->mChildren = new aiNode *[nodes.size()](); - parent->mNumChildren = static_cast(nodes.size()); - for (unsigned int i = 0; i < nodes.size(); ++i) { - parent->mChildren[i] = nodes[i].mOwnership.release(); + } else { + parent->mChildren = new aiNode *[nodes.size()](); + parent->mNumChildren = static_cast(nodes.size()); + for (unsigned int i = 0; i < nodes.size(); ++i) { + parent->mChildren[i] = nodes[i].mOwnership.release(); + } } } diff --git a/code/AssetLib/SMD/SMDLoader.cpp b/code/AssetLib/SMD/SMDLoader.cpp index 1eac5d934..5d7c8f94a 100644 --- a/code/AssetLib/SMD/SMDLoader.cpp +++ b/code/AssetLib/SMD/SMDLoader.cpp @@ -400,8 +400,12 @@ void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent) { } } + // nothing to do + if (pcNode->mNumChildren == 0) + return; + // now allocate the output array - pcNode->mChildren = new aiNode*[pcNode->mNumChildren]; + pcNode->mChildren = new aiNode *[pcNode->mNumChildren]; // and fill all subnodes unsigned int qq( 0 ); diff --git a/code/PostProcessing/ValidateDataStructure.cpp b/code/PostProcessing/ValidateDataStructure.cpp index 8441b48be..bd62e6c90 100644 --- a/code/PostProcessing/ValidateDataStructure.cpp +++ b/code/PostProcessing/ValidateDataStructure.cpp @@ -891,6 +891,9 @@ void ValidateDSProcess::Validate(const aiNode *pNode) { ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName); } } + } else if (pNode->mChildren) { + ReportError("aiNode::mChildren is not nullptr for empty node %s (aiNode::mNumChildren is %i)", + nodeName, pNode->mNumChildren); } } From f69e55058d044aca5f290aa6f29b6e8736c80816 Mon Sep 17 00:00:00 2001 From: "Tobias Rittig, Ph.D." Date: Tue, 3 Sep 2024 21:45:30 +0200 Subject: [PATCH 05/10] Allow usage of pugixml from a superproject (#5752) When using CMake subprojects with an existing build of pugixml this prevents Assimp from using its own copy. --- code/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 9b2708623..fb0fbc742 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1053,7 +1053,7 @@ ENDIF() # IF (ASSIMP_BUILD_USD_IMPORTER) IF(ASSIMP_HUNTER_ENABLED) hunter_add_package(pugixml) find_package(pugixml CONFIG REQUIRED) -ELSE() +ELSEIF(NOT TARGET pugixml::pugixml) SET( Pugixml_SRCS ../contrib/pugixml/src/pugiconfig.hpp ../contrib/pugixml/src/pugixml.hpp @@ -1439,6 +1439,9 @@ ELSE() if (ASSIMP_BUILD_DRACO) target_link_libraries(assimp ${draco_LIBRARIES}) endif() + if(TARGET pugixml::pugixml) + target_link_libraries(assimp pugixml::pugixml) + endif() ENDIF() if(ASSIMP_ANDROID_JNIIOSYSTEM) From ff2dc2fb2e6ac1777d5f632133710dd822dc4873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20M=C3=B6ller?= Date: Wed, 4 Sep 2024 11:54:24 +0200 Subject: [PATCH 06/10] Prevents PLY from parsing duplicate properties (#5743) Co-authored-by: Kim Kulling --- code/AssetLib/Ply/PlyParser.cpp | 29 +++++++++++++++ test/unit/utPLYImportExport.cpp | 66 +++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/code/AssetLib/Ply/PlyParser.cpp b/code/AssetLib/Ply/PlyParser.cpp index dbbabc03f..ffdd62efb 100644 --- a/code/AssetLib/Ply/PlyParser.cpp +++ b/code/AssetLib/Ply/PlyParser.cpp @@ -48,10 +48,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include namespace Assimp { +std::string to_string(EElementSemantic e) { + + switch (e) { + case EEST_Vertex: + return std::string{ "vertex" }; + case EEST_TriStrip: + return std::string{ "tristrips" }; + case EEST_Edge: + return std::string{ "edge" }; + case EEST_Material: + return std::string{ "material" }; + case EEST_TextureFile: + return std::string{ "TextureFile" }; + default: + return std::string{ "invalid" }; + } +} + // ------------------------------------------------------------------------------------------------ PLY::EDataType PLY::Property::ParseDataType(std::vector &buffer) { ai_assert(!buffer.empty()); @@ -281,6 +300,8 @@ bool PLY::Element::ParseElement(IOStreamBuffer &streamBuffer, std::vector< // if the exact semantic can't be determined, just store // the original string identifier pOut->szName = std::string(&buffer[0], &buffer[0] + strlen(&buffer[0])); + auto pos = pOut->szName.find_last_of(' '); + pOut->szName.erase(pos, pOut->szName.size()); } if (!PLY::DOM::SkipSpaces(buffer)) @@ -413,6 +434,7 @@ bool PLY::DOM::SkipComments(std::vector buffer) { bool PLY::DOM::ParseHeader(IOStreamBuffer &streamBuffer, std::vector &buffer, bool isBinary) { ASSIMP_LOG_VERBOSE_DEBUG("PLY::DOM::ParseHeader() begin"); + std::unordered_set definedAlElements; // parse all elements while (!buffer.empty()) { // skip all comments @@ -421,6 +443,13 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer &streamBuffer, std::vector PLY::Element out; if (PLY::Element::ParseElement(streamBuffer, buffer, &out)) { // add the element to the list of elements + + const auto propertyName = (out.szName.empty()) ? to_string(out.eSemantic) : out.szName; + auto alreadyDefined = definedAlElements.find(propertyName); + if (alreadyDefined != definedAlElements.end()) { + throw DeadlyImportError("Property '" + propertyName + "' in header already defined "); + } + definedAlElements.insert(propertyName); alElements.push_back(out); } else if (TokenMatch(buffer, "end_header", 10)) { // we have reached the end of the header diff --git a/test/unit/utPLYImportExport.cpp b/test/unit/utPLYImportExport.cpp index 54d7e4328..ecbe837d4 100644 --- a/test/unit/utPLYImportExport.cpp +++ b/test/unit/utPLYImportExport.cpp @@ -89,7 +89,7 @@ TEST_F(utPLYImportExport, exportTest_Success) { #endif // ASSIMP_BUILD_NO_EXPORT -//Test issue 1623, crash when loading two PLY files in a row +// Test issue 1623, crash when loading two PLY files in a row TEST_F(utPLYImportExport, importerMultipleTest) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", aiProcess_ValidateDataStructure); @@ -109,7 +109,7 @@ TEST_F(utPLYImportExport, importPLYwithUV) { EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene->mMeshes[0]); - //This test model is using n-gons, so 6 faces instead of 12 tris + // This test model is using n-gons, so 6 faces instead of 12 tris EXPECT_EQ(6u, scene->mMeshes[0]->mNumFaces); EXPECT_EQ(aiPrimitiveType_POLYGON, scene->mMeshes[0]->mPrimitiveTypes); EXPECT_EQ(true, scene->mMeshes[0]->HasTextureCoords(0)); @@ -121,7 +121,7 @@ TEST_F(utPLYImportExport, importBinaryPLY) { EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene->mMeshes[0]); - //This test model is double sided, so 12 faces instead of 6 + // This test model is double sided, so 12 faces instead of 6 EXPECT_EQ(12u, scene->mMeshes[0]->mNumFaces); } @@ -160,7 +160,7 @@ TEST_F(utPLYImportExport, vertexColorTest) { TEST_F(utPLYImportExport, pointcloudTest) { Assimp::Importer importer; - //Could not use aiProcess_ValidateDataStructure since it's missing faces. + // Could not use aiProcess_ValidateDataStructure since it's missing faces. const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/issue623.ply", 0); EXPECT_NE(nullptr, scene); @@ -192,7 +192,7 @@ static const char *test_file = TEST_F(utPLYImportExport, parseErrorTest) { Assimp::Importer importer; - //Could not use aiProcess_ValidateDataStructure since it's missing faces. + // Could not use aiProcess_ValidateDataStructure since it's missing faces. const aiScene *scene = importer.ReadFileFromMemory(test_file, strlen(test_file), 0); EXPECT_NE(nullptr, scene); } @@ -207,5 +207,57 @@ TEST_F(utPLYImportExport, parseInvalid) { TEST_F(utPLYImportExport, payload_JVN42386607) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/payload_JVN42386607", 0); - EXPECT_EQ(nullptr, scene); -} \ No newline at end of file + EXPECT_EQ(nullptr, scene); +} + +// Tests Issue #5729. Test, if properties defined multiple times. Unclear what to do, better to abort than to crash entirely +TEST_F(utPLYImportExport, parseInvalidDoubleProperty) { + const char data[] = "ply\n" + "format ascii 1.0\n" + "element vertex 4\n" + "property float x\n" + "property float y\n" + "property float z\n" + "element vertex 8\n" + "property float x\n" + "property float y\n" + "property float z\n" + "end_header\n" + "0.0 0.0 0.0 0.0 0.0 0.0\n" + "0.0 0.0 1.0 0.0 0.0 1.0\n" + "0.0 1.0 0.0 0.0 1.0 0.0\n" + "0.0 0.0 1.0\n" + "0.0 1.0 0.0 0.0 0.0 1.0\n" + "0.0 1.0 1.0 0.0 1.0 1.0\n"; + + Assimp::Importer importer; + const aiScene *scene = importer.ReadFileFromMemory(data, sizeof(data), 0); + EXPECT_EQ(nullptr, scene); +} + +// Tests Issue #5729. Test, if properties defined multiple times. Unclear what to do, better to abort than to crash entirely +TEST_F(utPLYImportExport, parseInvalidDoubleCustomProperty) { + const char data[] = "ply\n" + "format ascii 1.0\n" + "element vertex 4\n" + "property float x\n" + "property float y\n" + "property float z\n" + "element name 8\n" + "property float x\n" + "element name 5\n" + "property float x\n" + "end_header\n" + "0.0 0.0 0.0 100.0 10.0\n" + "0.0 0.0 1.0 200.0 20.0\n" + "0.0 1.0 0.0 300.0 30.0\n" + "0.0 1.0 1.0 400.0 40.0\n" + "0.0 0.0 0.0 500.0 50.0\n" + "0.0 0.0 1.0 600.0 60.0\n" + "0.0 1.0 0.0 700.0 70.0\n" + "0.0 1.0 1.0 800.0 80.0\n"; + + Assimp::Importer importer; + const aiScene *scene = importer.ReadFileFromMemory(data, sizeof(data), 0); + EXPECT_EQ(nullptr, scene); +} From ed3fccd5db222d91140a1d45af54a1c7379f3a6a Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:03:26 +0100 Subject: [PATCH 07/10] Add option to ignore FBX custom axes (#5754) AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION Default false Co-authored-by: Kim Kulling --- code/AssetLib/FBX/FBXConverter.cpp | 4 +++- code/AssetLib/FBX/FBXImportSettings.h | 3 +++ code/AssetLib/FBX/FBXImporter.cpp | 1 + include/assimp/config.h.in | 13 +++++++++++ test/unit/utFBXImporterExporter.cpp | 31 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index d9718685d..6ce00bb85 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -181,7 +181,9 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo if (out->mNumMeshes == 0) { out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; } else { - correctRootTransform(mSceneOut); + // Apply the FBX axis metadata unless requested not to + if (!doc.Settings().ignoreUpDirection) + correctRootTransform(mSceneOut); } } diff --git a/code/AssetLib/FBX/FBXImportSettings.h b/code/AssetLib/FBX/FBXImportSettings.h index 74290f7e0..bd355bd34 100644 --- a/code/AssetLib/FBX/FBXImportSettings.h +++ b/code/AssetLib/FBX/FBXImportSettings.h @@ -156,6 +156,9 @@ struct ImportSettings { /** Set to true to perform a conversion from cm to meter after the import */ bool convertToMeters; + + // Set to true to ignore the axis configuration in the file + bool ignoreUpDirection = false; }; } // namespace FBX diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index 3a8fb8b8a..491919bdc 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -117,6 +117,7 @@ void FBXImporter::SetupProperties(const Importer *pImp) { mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true); mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false); + mSettings.ignoreUpDirection = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, false); mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false); } diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index 5194a213c..95107f916 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -676,6 +676,19 @@ enum aiComponent #define AI_CONFIG_FBX_CONVERT_TO_M \ "AI_CONFIG_FBX_CONVERT_TO_M" +// --------------------------------------------------------------------------- +/** @brief Set whether the FBX importer shall ignore the provided axis configuration + * + * If this property is set to true, the axis directions provided in the FBX file + * will be ignored and the file will be loaded as is. + * + * Set to true for Assimp 5.3.x and earlier behavior + * Equivalent to AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION + * Property type: Bool. Default value: false. + */ +#define AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION \ + "AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION" + // --------------------------------------------------------------------------- /** @brief Will enable the skeleton struct to store bone data. * diff --git a/test/unit/utFBXImporterExporter.cpp b/test/unit/utFBXImporterExporter.cpp index 5cc40d216..940724670 100644 --- a/test/unit/utFBXImporterExporter.cpp +++ b/test/unit/utFBXImporterExporter.cpp @@ -311,6 +311,37 @@ TEST_F(utFBXImporterExporter, sceneMetadata) { } } +TEST_F(utFBXImporterExporter, importCustomAxes) { + // see https://github.com/assimp/assimp/issues/5494 + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure); + EXPECT_NE(nullptr, scene); + + // The ASCII box has customised the Up and Forward axes, verify that the RootNode transform has applied it + ASSERT_FALSE(scene->mRootNode->mTransformation.IsIdentity()) << "Did not apply the custom axis transform"; + + aiVector3D upVec{ 0, 0, 1 }; // Up is +Z + aiVector3D forwardVec{ 0, -1, 0 }; // Forward is -Y + aiVector3D rightVec{ 1, 0, 0 }; // Right is +X + aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f, + upVec.x, upVec.y, upVec.z, 0.0f, + forwardVec.x, forwardVec.y, forwardVec.z, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + + EXPECT_EQ(mat, scene->mRootNode->mTransformation); +} + +TEST_F(utFBXImporterExporter, importIgnoreCustomAxes) { + // see https://github.com/assimp/assimp/issues/5494 + Assimp::Importer importer; + importer.SetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, true); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure); + EXPECT_NE(nullptr, scene); + + // Verify that the RootNode transform has NOT applied the custom axes + EXPECT_TRUE(scene->mRootNode->mTransformation.IsIdentity()); +} + TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure); From cd0ef869e394d5ccc424e883d538d3eda008ab9d Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 5 Sep 2024 23:40:19 +0200 Subject: [PATCH 08/10] Kimkulling/mark blender versions as not supported (#5370) * Cleanup defs + add deprecated macro * Remove empty line * Remove dead code --------- Co-authored-by: Kim Kulling --- code/CMakeLists.txt | 3 +- include/assimp/defs.h | 200 ++++++++++++++++++++++++------------------ 2 files changed, 114 insertions(+), 89 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index fb0fbc742..e18c7c489 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1396,6 +1396,7 @@ IF (ASSIMP_WARNINGS_AS_ERRORS) -Wno-unused-template -Wno-undefined-func-template -Wno-declaration-after-statement + -Wno-deprecated-declarations ) ELSE() TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX) @@ -1417,9 +1418,7 @@ TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC IF(ASSIMP_HUNTER_ENABLED) TARGET_LINK_LIBRARIES(assimp PUBLIC - #polyclipping::polyclipping openddlparser::openddl_parser - #poly2tri::poly2tri minizip::minizip ZLIB::zlib RapidJSON::rapidjson diff --git a/include/assimp/defs.h b/include/assimp/defs.h index 38792c1c1..de921ce2f 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -49,14 +49,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_DEFINES_H_INC #ifdef __GNUC__ -#pragma GCC system_header +# pragma GCC system_header #endif #include ////////////////////////////////////////////////////////////////////////// -/* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific - * file format loader. The loader is be excluded from the +/** + * @brief Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific file format loader. + * + * The loader is be excluded from the * build in this case. 'XX' stands for the most common file * extension of the file format. E.g.: * ASSIMP_BUILD_NO_X_IMPORTER disables the X loader. @@ -76,34 +78,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ////////////////////////////////////////////////////////////////////////// #ifndef ASSIMP_BUILD_NO_COMPRESSED_X -#define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_Z_INFLATE #endif #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND -#define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_Z_INFLATE #endif #ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC -#define ASSIMP_BUILD_NEED_Z_INFLATE -#define ASSIMP_BUILD_NEED_UNZIP +# define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_UNZIP #endif #ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER -#define ASSIMP_BUILD_NEED_Z_INFLATE -#define ASSIMP_BUILD_NEED_UNZIP +# define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_UNZIP #endif -// We need those constants, workaround for any platforms where nobody defined them yet +/** + * @brief We need those constants, workaround for any platforms where nobody defined them yet. + */ #if (!defined SIZE_MAX) -#define SIZE_MAX (~((size_t)0)) +# define SIZE_MAX (~((size_t)0)) #endif -/*#if (!defined UINT_MAX) -#define UINT_MAX (~((unsigned int)0)) -#endif*/ - ////////////////////////////////////////////////////////////////////////// -/* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific +/** @brief Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific + * * post processing step. This is the current list of process names ('XX'): * CALCTANGENTS * JOINVERTICES @@ -134,46 +135,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OPTIMIZEGRAPH * GENENTITYMESHES * FIXTEXTUREPATHS - * GENBOUNDINGBOXES */ -////////////////////////////////////////////////////////////////////////// + * GENBOUNDINGBOXES + */ +////////////////////////////////////////////////////////////////////////// +/** @brief Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library + * + * Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in + * an external DLL under Windows. Default is static linkage. + */ +////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 -#undef ASSIMP_API -////////////////////////////////////////////////////////////////////////// -/* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */ -////////////////////////////////////////////////////////////////////////// -#ifdef ASSIMP_BUILD_DLL_EXPORT -#define ASSIMP_API __declspec(dllexport) -#define ASSIMP_API_WINONLY __declspec(dllexport) - -////////////////////////////////////////////////////////////////////////// -/* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in - * an external DLL under Windows. Default is static linkage. */ -////////////////////////////////////////////////////////////////////////// -#elif (defined ASSIMP_DLL) -#define ASSIMP_API __declspec(dllimport) -#define ASSIMP_API_WINONLY __declspec(dllimport) -#else -#define ASSIMP_API -#define ASSIMP_API_WINONLY -#endif -#elif defined(SWIG) -/* Do nothing, the relevant defines are all in AssimpSwigPort.i */ -#else -#define ASSIMP_API __attribute__((visibility("default"))) -#define ASSIMP_API_WINONLY +# undef ASSIMP_API +# ifdef ASSIMP_BUILD_DLL_EXPORT +# define ASSIMP_API __declspec(dllexport) +# define ASSIMP_API_WINONLY __declspec(dllexport) +# elif (defined ASSIMP_DLL) +# define ASSIMP_API __declspec(dllimport) +# define ASSIMP_API_WINONLY __declspec(dllimport) +# else +# define ASSIMP_API +# define ASSIMP_API_WINONLY +# endif +#else +# define ASSIMP_API __attribute__((visibility("default"))) +# define ASSIMP_API_WINONLY #endif // _WIN32 +/** + * @brief Helper macros + * + * @def AI_FORCE_INLINE + * @brief Force the compiler to inline a function, if possible + * + * @def AI_WONT_RETURN + * @brief Tells the compiler that a function never returns. + * + * Used in code analysis to skip dead paths (e.g. after an assertion evaluated to false). + */ #ifdef _MSC_VER #pragma warning(disable : 4521 4512 4714 4127 4351 4510) #ifdef ASSIMP_BUILD_DLL_EXPORT #pragma warning(disable : 4251) #endif - /* Force the compiler to inline a function, if possible */ #define AI_FORCE_INLINE inline - - /* Tells the compiler that a function never returns. Used in code analysis - * to skip dead paths (e.g. after an assertion evaluated to false). */ #define AI_WONT_RETURN __declspec(noreturn) #elif defined(SWIG) /* Do nothing, the relevant defines are all in AssimpSwigPort.i */ @@ -223,29 +228,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * to typedef all structs/enums. */ ////////////////////////////////////////////////////////////////////////// #if (defined ASSIMP_DOXYGEN_BUILD) -#define C_STRUCT -#define C_ENUM +# define C_STRUCT +# define C_ENUM #else -#define C_STRUCT struct -#define C_ENUM enum +# define C_STRUCT struct +# define C_ENUM enum #endif #endif #if (defined(__BORLANDC__) || defined(__BCPLUSPLUS__)) -#error Currently, Borland is unsupported. Feel free to port Assimp. +# error Currently, Borland is unsupported. Feel free to port Assimp. #endif ////////////////////////////////////////////////////////////////////////// -/* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp - * without threading support. The library doesn't utilize - * threads then and is itself not threadsafe. */ +/** + * Define ASSIMP_BUILD_SINGLETHREADED to compile assimp + * without threading support. The library doesn't utilize + * threads then and is itself not threadsafe. + */ ////////////////////////////////////////////////////////////////////////// #ifndef ASSIMP_BUILD_SINGLETHREADED -#define ASSIMP_BUILD_SINGLETHREADED +# define ASSIMP_BUILD_SINGLETHREADED #endif #if defined(_DEBUG) || !defined(NDEBUG) -#define ASSIMP_BUILD_DEBUG +# define ASSIMP_BUILD_DEBUG #endif ////////////////////////////////////////////////////////////////////////// @@ -291,55 +298,74 @@ typedef unsigned int ai_uint; #ifdef __cplusplus constexpr ai_real ai_epsilon = (ai_real) 1e-6; #else -#define ai_epsilon ((ai_real)1e-6) -#endif - -/* Support for big-endian builds */ -#if defined(__BYTE_ORDER__) -#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#if !defined(__BIG_ENDIAN__) -#define __BIG_ENDIAN__ -#endif -#else /* little endian */ -#if defined(__BIG_ENDIAN__) -#undef __BIG_ENDIAN__ -#endif -#endif -#endif -#if defined(__BIG_ENDIAN__) -#define AI_BUILD_BIG_ENDIAN +# define ai_epsilon ((ai_real)1e-6) #endif /** - * To avoid running out of memory + * @brief Support for big-endian builds + * + * This will check which byte ordering is used on the target architecture. + */ +#if defined(__BYTE_ORDER__) +# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# if !defined(__BIG_ENDIAN__) +# define __BIG_ENDIAN__ +# endif +# else /* little endian */ +# if defined(__BIG_ENDIAN__) +# undef __BIG_ENDIAN__ +# endif +# endif +#endif +#if defined(__BIG_ENDIAN__) +# define AI_BUILD_BIG_ENDIAN +#endif + +/** + * @brief To avoid running out of memory + * * This can be adjusted for specific use cases * It's NOT a total limit, just a limit for individual allocations */ #define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type)) #ifndef _MSC_VER -#if __cplusplus >= 201103L // C++11 -#define AI_NO_EXCEPT noexcept +# if __cplusplus >= 201103L // C++11 +# define AI_NO_EXCEPT noexcept +# else +# define AI_NO_EXCEPT +# endif #else -#define AI_NO_EXCEPT -#endif -#else -#if (_MSC_VER >= 1915) -#define AI_NO_EXCEPT noexcept -#else -#define AI_NO_EXCEPT -#endif +# if (_MSC_VER >= 1915) +# define AI_NO_EXCEPT noexcept +# else +# define AI_NO_EXCEPT +# endif #endif // _MSC_VER /** - * Helper macro to set a pointer to NULL in debug builds + * @brief Helper macro to set a pointer to NULL in debug builds */ #if (defined ASSIMP_BUILD_DEBUG) -#define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; +# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; #else -#define AI_DEBUG_INVALIDATE_PTR(x) +# define AI_DEBUG_INVALIDATE_PTR(x) #endif #define AI_COUNT_OF(X) (sizeof(X) / sizeof((X)[0])) +/** + * @brief Will mark functions or classes as deprecated. + * + * Deprecation means that we will remove this function, class or methods in the next m + */ +#if defined(__GNUC__) || defined(__clang__) +# define AI_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define AI_DEPRECATED __declspec(deprecated) +#else +# pragma message("WARNING: You need to implement DEPRECATED for this compiler") +# define AI_DEPRECATED +#endif + #endif // !! AI_DEFINES_H_INC From 4024726eca89331503bdab33d0b9186e901bbc45 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 7 Sep 2024 21:02:34 +0200 Subject: [PATCH 09/10] Fix leak (#5762) * Fix leak * Update utLogger.cpp --- code/Common/Assimp.cpp | 13 ++++++--- fuzz/assimp_fuzzer.cc | 2 +- test/CMakeLists.txt | 1 + test/unit/Common/utLogger.cpp | 52 +++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/unit/Common/utLogger.cpp diff --git a/code/Common/Assimp.cpp b/code/Common/Assimp.cpp index ef3ee7b5d..91896e405 100644 --- a/code/Common/Assimp.cpp +++ b/code/Common/Assimp.cpp @@ -359,20 +359,25 @@ void CallbackToLogRedirector(const char *msg, char *dt) { s->write(msg); } +static LogStream *DefaultStream = nullptr; + // ------------------------------------------------------------------------------------------------ ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream, const char *file) { aiLogStream sout; ASSIMP_BEGIN_EXCEPTION_REGION(); - LogStream *stream = LogStream::createDefaultStream(pStream, file); - if (!stream) { + if (DefaultStream == nullptr) { + DefaultStream = LogStream::createDefaultStream(pStream, file); + } + + if (!DefaultStream) { sout.callback = nullptr; sout.user = nullptr; } else { sout.callback = &CallbackToLogRedirector; - sout.user = (char *)stream; + sout.user = (char *)DefaultStream; } - gPredefinedStreams.push_back(stream); + gPredefinedStreams.push_back(DefaultStream); ASSIMP_END_EXCEPTION_REGION(aiLogStream); return sout; } diff --git a/fuzz/assimp_fuzzer.cc b/fuzz/assimp_fuzzer.cc index 8178674e8..91ffd9d69 100644 --- a/fuzz/assimp_fuzzer.cc +++ b/fuzz/assimp_fuzzer.cc @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) { - aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL); + aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr); aiAttachLogStream(&stream); Importer importer; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7b7fd850a..1a45adac7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -100,6 +100,7 @@ SET( COMMON unit/Common/utBase64.cpp unit/Common/utHash.cpp unit/Common/utBaseProcess.cpp + unit/Common/utLogger.cpp ) SET(Geometry diff --git a/test/unit/Common/utLogger.cpp b/test/unit/Common/utLogger.cpp new file mode 100644 index 000000000..932240a7f --- /dev/null +++ b/test/unit/Common/utLogger.cpp @@ -0,0 +1,52 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2024, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above +copyright notice, this list of conditions and the +following disclaimer. + +* Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other +materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its +contributors may be used to endorse or promote products +derived from this software without specific prior +written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +#include "UnitTestPCH.h" +#include + +using namespace Assimp; +class utLogger : public ::testing::Test {}; + +TEST_F(utLogger, aiGetPredefinedLogStream_leak_test) { + aiLogStream stream1 = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr); + aiLogStream stream2 = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT, nullptr); + ASSERT_EQ(stream1.callback, stream2.callback); +} From d468e633b1b5cf20b893ef0315006fa6b901ca8d Mon Sep 17 00:00:00 2001 From: dataisland Date: Tue, 10 Sep 2024 02:12:01 -0500 Subject: [PATCH 10/10] Fix invalid access (#5765) * Fix invalid access * Update SortByPTypeProcess.cpp Some smaller refactorings. * Update SortByPTypeProcess.cpp Small refactorings. --------- Co-authored-by: Kim Kulling --- code/PostProcessing/SortByPTypeProcess.cpp | 54 ++++++++++++++-------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/code/PostProcessing/SortByPTypeProcess.cpp b/code/PostProcessing/SortByPTypeProcess.cpp index 48ebbc573..76b685d58 100644 --- a/code/PostProcessing/SortByPTypeProcess.cpp +++ b/code/PostProcessing/SortByPTypeProcess.cpp @@ -65,37 +65,47 @@ void SortByPTypeProcess::SetupProperties(const Importer *pImp) { mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, 0); } +// ------------------------------------------------------------------------------------------------ +static void clearMeshesInNode(aiNode *node) { + delete[] node->mMeshes; + node->mNumMeshes = 0; + node->mMeshes = nullptr; +} + // ------------------------------------------------------------------------------------------------ // Update changed meshes in all nodes void UpdateNodes(const std::vector &replaceMeshIndex, aiNode *node) { + ai_assert(node != nullptr); + if (node->mNumMeshes) { unsigned int newSize = 0; for (unsigned int m = 0; m < node->mNumMeshes; ++m) { unsigned int add = node->mMeshes[m] << 2; for (unsigned int i = 0; i < 4; ++i) { - if (UINT_MAX != replaceMeshIndex[add + i]) ++newSize; - } - } - if (!newSize) { - delete[] node->mMeshes; - node->mNumMeshes = 0; - node->mMeshes = nullptr; - } else { - // Try to reuse the old array if possible - unsigned int *newMeshes = (newSize > node->mNumMeshes ? new unsigned int[newSize] : node->mMeshes); - - for (unsigned int m = 0; m < node->mNumMeshes; ++m) { - unsigned int add = node->mMeshes[m] << 2; - for (unsigned int i = 0; i < 4; ++i) { - if (UINT_MAX != replaceMeshIndex[add + i]) - *newMeshes++ = replaceMeshIndex[add + i]; + if (UINT_MAX != replaceMeshIndex[add + i]) { + ++newSize; } } - if (newSize > node->mNumMeshes) - delete[] node->mMeshes; - - node->mMeshes = newMeshes - (node->mNumMeshes = newSize); } + if (newSize == 0) { + clearMeshesInNode(node); + return; + } + + // Try to reuse the old array if possible + unsigned int *newMeshes = (newSize > node->mNumMeshes ? new unsigned int[newSize] : node->mMeshes); + for (unsigned int m = 0; m < node->mNumMeshes; ++m) { + unsigned int add = node->mMeshes[m] << 2; + for (unsigned int i = 0; i < 4; ++i) { + if (UINT_MAX != replaceMeshIndex[add + i]) { + *newMeshes++ = replaceMeshIndex[add + i]; + } + } + } + if (newSize > node->mNumMeshes) { + clearMeshesInNode(node); + } + node->mMeshes = newMeshes - (node->mNumMeshes = newSize); } // call all subnodes recursively @@ -167,6 +177,10 @@ void SortByPTypeProcess::Execute(aiScene *pScene) { // with the largest number of primitives unsigned int aiNumPerPType[4] = { 0, 0, 0, 0 }; aiFace *pFirstFace = mesh->mFaces; + if (pFirstFace == nullptr) { + continue; + } + aiFace *const pLastFace = pFirstFace + mesh->mNumFaces; unsigned int numPolyVerts = 0;