From 065c264b34fc3151acfe215af5fece11d5010c67 Mon Sep 17 00:00:00 2001 From: Alexandre Avenel Date: Sun, 4 Mar 2018 12:52:38 +0100 Subject: [PATCH 1/4] Fix #1415 : float-color.ply is broken float-color.ply was broken because it doesn't have a newline at the end. I'm not sure if a file without newline should be considered valid ? Added more checks to float-color unit-test in order to fail as excepted. Fixed the shipped unit test. Add postprocess validation to PLY unit tests --- test/models/PLY/float-color.ply | 2 +- test/unit/utPLYImportExport.cpp | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/test/models/PLY/float-color.ply b/test/models/PLY/float-color.ply index 34353ad53..f419be34e 100644 --- a/test/models/PLY/float-color.ply +++ b/test/models/PLY/float-color.ply @@ -15,4 +15,4 @@ end_header 0.0 0.0 0.0 0 0 1 1 100.0 0.0 0.0 0 0 1 1 200.0 200.0 0.0 0 0 1 1 -3 0 1 2 \ No newline at end of file +3 0 1 2 diff --git a/test/unit/utPLYImportExport.cpp b/test/unit/utPLYImportExport.cpp index 633beda5f..900f494f8 100644 --- a/test/unit/utPLYImportExport.cpp +++ b/test/unit/utPLYImportExport.cpp @@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include "AbstractImportExportBase.h" +#include using namespace ::Assimp; @@ -52,7 +53,7 @@ class utPLYImportExport : public AbstractImportExportBase { public: virtual bool importerTest() { Assimp::Importer importer; - const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", 0 ); + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", aiProcess_ValidateDataStructure); EXPECT_EQ( 1u, scene->mNumMeshes ); EXPECT_NE( nullptr, scene->mMeshes[0] ); EXPECT_EQ( 8u, scene->mMeshes[0]->mNumVertices ); @@ -65,7 +66,7 @@ public: virtual bool exporterTest() { Importer importer; Exporter exporter; - const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", 0); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "ply", ASSIMP_TEST_MODELS_DIR "/PLY/cube_test.ply")); @@ -89,19 +90,28 @@ TEST_F(utPLYImportExport, exportTest_Success ) { //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", 0); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); - scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", 0); + scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube.ply", aiProcess_ValidateDataStructure); EXPECT_NE(nullptr, scene); } TEST_F( utPLYImportExport, vertexColorTest ) { Assimp::Importer importer; - const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/float-color.ply", 0 ); + const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/float-color.ply", aiProcess_ValidateDataStructure); EXPECT_NE( nullptr, scene ); + EXPECT_EQ(1u, scene->mMeshes[0]->mNumFaces); + EXPECT_EQ(aiPrimitiveType_TRIANGLE, scene->mMeshes[0]->mPrimitiveTypes); + EXPECT_EQ(true, scene->mMeshes[0]->HasVertexColors(0)); + + auto first_face = scene->mMeshes[0]->mFaces[0]; + EXPECT_EQ(3, first_face.mNumIndices); + EXPECT_EQ(0, first_face.mIndices[0]); + EXPECT_EQ(1, first_face.mIndices[1]); + EXPECT_EQ(2, first_face.mIndices[2]); } static const char *test_file = @@ -125,6 +135,6 @@ static const char *test_file = TEST_F( utPLYImportExport, parseErrorTest ) { Assimp::Importer importer; - const aiScene *scene = importer.ReadFileFromMemory( test_file, strlen( test_file ), 0 ); + const aiScene *scene = importer.ReadFileFromMemory( test_file, strlen( test_file ), aiProcess_ValidateDataStructure); EXPECT_NE( nullptr, scene ); } From cd5881c9c05941f915c551416c2ef4673fb34e49 Mon Sep 17 00:00:00 2001 From: Alexandre Avenel Date: Sun, 4 Mar 2018 13:07:40 +0100 Subject: [PATCH 2/4] Add unit-test for PLY with UV coordinates --- test/models/PLY/cube_uv.ply | 45 +++++++++++++++++++++++++++++++++ test/unit/utPLYImportExport.cpp | 12 +++++++++ 2 files changed, 57 insertions(+) create mode 100644 test/models/PLY/cube_uv.ply diff --git a/test/models/PLY/cube_uv.ply b/test/models/PLY/cube_uv.ply new file mode 100644 index 000000000..45ab0607a --- /dev/null +++ b/test/models/PLY/cube_uv.ply @@ -0,0 +1,45 @@ +ply +format ascii 1.0 +comment Created by Blender 2.77 (sub 0) - www.blender.org, source file: '' +element vertex 24 +property float x +property float y +property float z +property float nx +property float ny +property float nz +property float s +property float t +element face 6 +property list uchar uint vertex_indices +end_header +1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 +1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000 1.000000 0.000000 +-1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000 1.000000 1.000000 +-1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000 0.000000 1.000000 +1.000000 0.999999 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 +-1.000000 1.000000 1.000000 0.000000 -0.000000 1.000000 1.000000 0.000000 +-1.000000 -1.000000 1.000000 0.000000 -0.000000 1.000000 1.000000 1.000000 +0.999999 -1.000001 1.000000 0.000000 -0.000000 1.000000 0.000000 1.000000 +1.000000 1.000000 -1.000000 1.000000 -0.000000 0.000000 0.000000 0.000000 +1.000000 0.999999 1.000000 1.000000 -0.000000 0.000000 1.000000 0.000000 +0.999999 -1.000001 1.000000 1.000000 -0.000000 0.000000 1.000000 1.000000 +1.000000 -1.000000 -1.000000 1.000000 -0.000000 0.000000 0.000000 1.000000 +1.000000 -1.000000 -1.000000 -0.000000 -1.000000 -0.000000 0.000000 0.000000 +0.999999 -1.000001 1.000000 -0.000000 -1.000000 -0.000000 1.000000 0.000000 +-1.000000 -1.000000 1.000000 -0.000000 -1.000000 -0.000000 1.000000 1.000000 +-1.000000 -1.000000 -1.000000 -0.000000 -1.000000 -0.000000 0.000000 1.000000 +-1.000000 -1.000000 -1.000000 -1.000000 0.000000 -0.000000 0.000000 0.000000 +-1.000000 -1.000000 1.000000 -1.000000 0.000000 -0.000000 1.000000 0.000000 +-1.000000 1.000000 1.000000 -1.000000 0.000000 -0.000000 1.000000 1.000000 +-1.000000 1.000000 -1.000000 -1.000000 0.000000 -0.000000 0.000000 1.000000 +1.000000 0.999999 1.000000 0.000000 1.000000 0.000000 0.000000 0.000000 +1.000000 1.000000 -1.000000 0.000000 1.000000 0.000000 1.000000 0.000000 +-1.000000 1.000000 -1.000000 0.000000 1.000000 0.000000 1.000000 1.000000 +-1.000000 1.000000 1.000000 0.000000 1.000000 0.000000 0.000000 1.000000 +4 0 1 2 3 +4 4 5 6 7 +4 8 9 10 11 +4 12 13 14 15 +4 16 17 18 19 +4 20 21 22 23 diff --git a/test/unit/utPLYImportExport.cpp b/test/unit/utPLYImportExport.cpp index 900f494f8..0bef096e7 100644 --- a/test/unit/utPLYImportExport.cpp +++ b/test/unit/utPLYImportExport.cpp @@ -99,6 +99,18 @@ TEST_F(utPLYImportExport, importerMultipleTest) { EXPECT_NE(nullptr, scene); } +TEST_F(utPLYImportExport, importPLYwithUV) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube_uv.ply", aiProcess_ValidateDataStructure); + + EXPECT_NE(nullptr, scene); + EXPECT_NE(nullptr, scene->mMeshes[0]); + //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)); +} + TEST_F( utPLYImportExport, vertexColorTest ) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/float-color.ply", aiProcess_ValidateDataStructure); From bd80e92f788215708b5a0b7f3600c6d69df5c1ce Mon Sep 17 00:00:00 2001 From: Alexandre Avenel Date: Sun, 4 Mar 2018 12:42:21 +0100 Subject: [PATCH 3/4] Add PLY loader unit test for binary files --- test/models/PLY/cube_binary.ply | Bin 0 -> 447 bytes test/unit/utPLYImportExport.cpp | 10 ++++++++++ 2 files changed, 10 insertions(+) create mode 100644 test/models/PLY/cube_binary.ply diff --git a/test/models/PLY/cube_binary.ply b/test/models/PLY/cube_binary.ply new file mode 100644 index 0000000000000000000000000000000000000000..14d29ebd86d5be53fedd1933abe9b1bf95671c59 GIT binary patch literal 447 zcmZvW!EVAZ5JUrMLGoAZ7gSA8+>qdakb34C8D|5Q949iSBAobic8tmMeshes[0]->HasTextureCoords(0)); } +TEST_F(utPLYImportExport, importBinaryPLY) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/cube_binary.ply", 0); + + EXPECT_NE(nullptr, scene); + EXPECT_NE(nullptr, scene->mMeshes[0]); + //This test model is double sided, so 12 faces instead of 6 + EXPECT_EQ(12u, scene->mMeshes[0]->mNumFaces); +} + TEST_F( utPLYImportExport, vertexColorTest ) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/PLY/float-color.ply", aiProcess_ValidateDataStructure); From d2547e84f530fa5a243f95068a17f50178f3ad47 Mon Sep 17 00:00:00 2001 From: Alexandre Avenel Date: Sun, 4 Mar 2018 21:41:19 +0100 Subject: [PATCH 4/4] Fix for undefined behavior when loading binary PLY This commit fix undefined behavior reported by UBSAN when loading a binary PLY file. --- code/PlyParser.cpp | 68 ++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/code/PlyParser.cpp b/code/PlyParser.cpp index 85c0f823e..672ac9bde 100644 --- a/code/PlyParser.cpp +++ b/code/PlyParser.cpp @@ -1043,71 +1043,91 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer &streamBuffer, switch (eType) { case EDT_UInt: - out->iUInt = (uint32_t)*((uint32_t*)pCur); - pCur += 4; + { + uint32_t t; + memcpy(&t, pCur, sizeof(uint32_t)); + pCur += sizeof(uint32_t); // Swap endianness - if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt); + if (p_bBE)ByteSwap::Swap(&t); + out->iUInt = t; break; + } case EDT_UShort: { - uint16_t i = *((uint16_t*)pCur); + uint16_t t; + memcpy(&t, pCur, sizeof(uint16_t)); + pCur += sizeof(uint16_t); // Swap endianness - if (p_bBE)ByteSwap::Swap(&i); - out->iUInt = (uint32_t)i; - pCur += 2; + if (p_bBE)ByteSwap::Swap(&t); + out->iUInt = t; break; } case EDT_UChar: { - out->iUInt = (uint32_t)(*((uint8_t*)pCur)); - pCur++; + uint8_t t; + memcpy(&t, pCur, sizeof(uint8_t)); + pCur += sizeof(uint8_t); + out->iUInt = t; break; } case EDT_Int: - out->iInt = *((int32_t*)pCur); - pCur += 4; + { + int32_t t; + memcpy(&t, pCur, sizeof(int32_t)); + pCur += sizeof(int32_t); // Swap endianness - if (p_bBE)ByteSwap::Swap(&out->iInt); + if (p_bBE)ByteSwap::Swap(&t); + out->iInt = t; break; + } case EDT_Short: { - int16_t i = *((int16_t*)pCur); + int16_t t; + memcpy(&t, pCur, sizeof(int16_t)); + pCur += sizeof(int16_t); // Swap endianness - if (p_bBE)ByteSwap::Swap(&i); - out->iInt = (int32_t)i; - pCur += 2; + if (p_bBE)ByteSwap::Swap(&t); + out->iInt = t; break; } case EDT_Char: - out->iInt = (int32_t)*((int8_t*)pCur); - pCur++; + { + int8_t t; + memcpy(&t, pCur, sizeof(int8_t)); + pCur += sizeof(int8_t); + out->iInt = t; break; + } case EDT_Float: { - out->fFloat = *((float*)pCur); + float t; + memcpy(&t, pCur, sizeof(float)); + pCur += sizeof(float); // Swap endianness - if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat); - pCur += 4; + if (p_bBE)ByteSwap::Swap(&t); + out->fFloat = t; break; } case EDT_Double: { - out->fDouble = *((double*)pCur); + double t; + memcpy(&t, pCur, sizeof(double)); + pCur += sizeof(double); // Swap endianness - if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble); - pCur += 8; + if (p_bBE)ByteSwap::Swap(&t); + out->fDouble = t; break; } default: