From 8a885e14b84ba2b474c6676abd534ec000c1e0f3 Mon Sep 17 00:00:00 2001 From: Vincent de Marignac Date: Wed, 15 Aug 2018 23:13:00 +0300 Subject: [PATCH 1/4] Produce an error and return when indices and data dont match. --- tiny_obj_loader.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 025f112..c87435d 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -1789,6 +1789,10 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, unsigned int current_smoothing_id = 0; // Initial value. 0 means no smoothing. + int greatest_vertex_index = -1; + int greatest_normal_index = -1; + int greatest_texcoord_index = -1; + shape_t shape; size_t line_num = 0; @@ -1907,6 +1911,10 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, return false; } + greatest_vertex_index = std::max(greatest_vertex_index, vi.v_idx); + greatest_normal_index = std::max(greatest_normal_index, vi.vn_idx); + greatest_texcoord_index = std::max(greatest_texcoord_index, vi.vt_idx); + face.vertex_indices.push_back(vi); size_t n = strspn(token, " \t\r"); token += n; @@ -2153,6 +2161,18 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, // Ignore unknown command. } + if (greatest_vertex_index >= v.size() + || greatest_normal_index >= vn.size() + || greatest_texcoord_index >= vt.size()) + { + if (err) { + std::stringstream ss; + ss << "WARN: Indices do not match the data.\n" << std::endl; + (*err) += ss.str(); + } + return false; + } + bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name, triangulate, v); // exportGroupsToShape return false when `usemtl` is called in the last From fdc70abdc6968a6adff55e7fd4999daed0efeada Mon Sep 17 00:00:00 2001 From: Vincent de Marignac Date: Wed, 15 Aug 2018 23:41:35 +0300 Subject: [PATCH 2/4] fix index comparison wrt array size --- tiny_obj_loader.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index c87435d..cfeb848 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -2161,9 +2161,9 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, // Ignore unknown command. } - if (greatest_vertex_index >= v.size() - || greatest_normal_index >= vn.size() - || greatest_texcoord_index >= vt.size()) + if (greatest_vertex_index * 3 >= int(v.size()) + || greatest_normal_index * 3 >= int(vn.size()) + || greatest_texcoord_index * 2 >= int(vt.size())) { if (err) { std::stringstream ss; From 7d20e9b9011cbc236e5569bc6a5cea6b1a853a7c Mon Sep 17 00:00:00 2001 From: Vincent de Marignac Date: Thu, 16 Aug 2018 00:00:22 +0300 Subject: [PATCH 3/4] use ternary op instead of max from omitted lib --- tiny_obj_loader.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index cfeb848..187d2b8 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -1789,9 +1789,9 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, unsigned int current_smoothing_id = 0; // Initial value. 0 means no smoothing. - int greatest_vertex_index = -1; - int greatest_normal_index = -1; - int greatest_texcoord_index = -1; + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; shape_t shape; @@ -1911,9 +1911,9 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, return false; } - greatest_vertex_index = std::max(greatest_vertex_index, vi.v_idx); - greatest_normal_index = std::max(greatest_normal_index, vi.vn_idx); - greatest_texcoord_index = std::max(greatest_texcoord_index, vi.vt_idx); + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; face.vertex_indices.push_back(vi); size_t n = strspn(token, " \t\r"); @@ -2161,9 +2161,9 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, // Ignore unknown command. } - if (greatest_vertex_index * 3 >= int(v.size()) - || greatest_normal_index * 3 >= int(vn.size()) - || greatest_texcoord_index * 2 >= int(vt.size())) + if (greatest_v_idx * 3 >= int(v.size()) + || greatest_vn_idx * 3 >= int(vn.size()) + || greatest_vt_idx * 2 >= int(vt.size())) { if (err) { std::stringstream ss; From 68350e2fc76b3ca1bc1d6c914d31b4e5ab8b2a02 Mon Sep 17 00:00:00 2001 From: Vincent de Marignac Date: Thu, 16 Aug 2018 23:34:47 +0300 Subject: [PATCH 4/4] give respective warnings but allow partially correct data to be returned --- tiny_obj_loader.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 187d2b8..d52e97c 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -2161,16 +2161,29 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, // Ignore unknown command. } - if (greatest_v_idx * 3 >= int(v.size()) - || greatest_vn_idx * 3 >= int(vn.size()) - || greatest_vt_idx * 2 >= int(vt.size())) + if (greatest_v_idx >= static_cast(v.size() / 3)) { if (err) { std::stringstream ss; - ss << "WARN: Indices do not match the data.\n" << std::endl; + ss << "WARN: Vertex indices out of bounds.\n" << std::endl; + (*err) += ss.str(); + } + } + if (greatest_vn_idx >= static_cast(vn.size() / 3)) + { + if (err) { + std::stringstream ss; + ss << "WARN: Vertex normal indices out of bounds.\n" << std::endl; + (*err) += ss.str(); + } + } + if (greatest_vt_idx >= static_cast(vt.size() / 2)) + { + if (err) { + std::stringstream ss; + ss << "WARN: Vertex texcoord indices out of bounds.\n" << std::endl; (*err) += ss.str(); } - return false; } bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material,