From dfb774213dde99d9864eaebb5fb876be281c4ba6 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Thu, 11 Apr 2024 17:21:16 +0300 Subject: [PATCH] Fix #120488: PLY importer crashes on degenerate (1 or 2 vertex) faces Make it match behavior of the previous Python importer: it was accepting such faces, and then always calling mesh validation function that got rid of them. Instead of doing the whole validation cost, just do not add such faces in the first place. --- .../io/ply/importer/ply_import_data.cc | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/source/blender/io/ply/importer/ply_import_data.cc b/source/blender/io/ply/importer/ply_import_data.cc index 4b364e8e599..ce6732c5b6c 100644 --- a/source/blender/io/ply/importer/ply_import_data.cc +++ b/source/blender/io/ply/importer/ply_import_data.cc @@ -437,6 +437,12 @@ static const char *load_face_element(PlyReadBuffer &file, if (count < 1 || count > 255) { return "Invalid face size, must be between 1 and 255"; } + /* Previous python based importer was accepting faces with fewer + * than 3 vertices, and silently dropping them. */ + if (count < 3) { + fprintf(stderr, "PLY Importer: ignoring face %i (%i vertices)\n", i, count); + continue; + } for (int j = 0; j < count; j++) { int index; @@ -467,15 +473,22 @@ static const char *load_face_element(PlyReadBuffer &file, scratch.resize(count * data_type_size[prop.type]); file.read_bytes(scratch.data(), scratch.size()); - ptr = scratch.data(); - if (header.type == PlyFormatType::BINARY_BE) { - endian_switch_array((uint8_t *)ptr, data_type_size[prop.type], count); + /* Previous python based importer was accepting faces with fewer + * than 3 vertices, and silently dropping them. */ + if (count < 3) { + fprintf(stderr, "PLY Importer: ignoring face %i (%i vertices)\n", i, count); } - for (int j = 0; j < count; ++j) { - uint32_t index = get_binary_value(prop.type, ptr); - data->face_vertices.append(index); + else { + ptr = scratch.data(); + if (header.type == PlyFormatType::BINARY_BE) { + endian_switch_array((uint8_t *)ptr, data_type_size[prop.type], count); + } + for (int j = 0; j < count; ++j) { + uint32_t index = get_binary_value(prop.type, ptr); + data->face_vertices.append(index); + } + data->face_sizes.append(count); } - data->face_sizes.append(count); /* Skip any properties after vertex indices. */ for (int j = prop_index + 1; j < element.properties.size(); j++) {