Skip to content

Commit

Permalink
Verify GLTF indices to prevent crash with corrupt files
Browse files Browse the repository at this point in the history
Also verify prior to vertex optimization.
  • Loading branch information
lawnjelly committed Jul 31, 2024
1 parent b58d16f commit 3771078
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
14 changes: 14 additions & 0 deletions core/math/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1549,3 +1549,17 @@ void Geometry::sort_polygon_winding(Vector<Vector2> &r_verts, bool p_clockwise)
r_verts.invert();
}
}

bool Geometry::verify_indices(const int *p_indices, int p_num_indices, int p_num_vertices) {
ERR_FAIL_NULL_V(p_indices, false);
ERR_FAIL_COND_V(p_num_indices < 0, false);
ERR_FAIL_COND_V(p_num_vertices < 0, false);

for (int n = 0; n < p_num_indices; n++) {
if ((unsigned int)p_indices[n] >= (unsigned int)p_num_vertices) {
return false;
}
}

return true;
}
1 change: 1 addition & 0 deletions core/math/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,7 @@ class Geometry {
static Vector<Vector3> compute_convex_mesh_points(const Plane *p_planes, int p_plane_count, real_t p_epsilon = CMP_EPSILON);
static bool convex_hull_intersects_convex_hull(const Plane *p_planes_a, int p_plane_count_a, const Plane *p_planes_b, int p_plane_count_b);
static real_t calculate_convex_hull_volume(const Geometry::MeshData &p_md);
static bool verify_indices(const int *p_indices, int p_num_indices, int p_num_vertices);

private:
static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
Expand Down
4 changes: 4 additions & 0 deletions core/math/vertex_cache_optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "vertex_cache_optimizer.h"

#include "core/math/geometry.h"
#include "core/math/math_funcs.h"

// Precalculate the tables.
Expand Down Expand Up @@ -287,6 +288,9 @@ bool VertexCacheOptimizer::reorder_indices_pool(PoolVector<int> &r_indices, uint
}

bool VertexCacheOptimizer::reorder_indices(LocalVector<int> &r_indices, uint32_t p_num_triangles, uint32_t p_num_verts) {
// If the mesh contains invalid indices, abort.
ERR_FAIL_COND_V(!Geometry::verify_indices(r_indices.ptr(), r_indices.size(), p_num_verts), false);

LocalVector<int> temp;
temp.resize(r_indices.size());
if (_reorder_indices((VERTEX_INDEX_TYPE *)temp.ptr(), (VERTEX_INDEX_TYPE *)r_indices.ptr(), p_num_triangles, p_num_verts)) {
Expand Down
14 changes: 14 additions & 0 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2936,6 +2936,20 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) {
mat = mat3d;
}
int32_t mat_idx = import_mesh->get_surface_count();

// Check for invalid indices.
if (array[Mesh::ARRAY_INDEX] && array[Mesh::ARRAY_INDEX] != Variant()) {
const Vector<int> &inds = array[Mesh::ARRAY_INDEX];

if (array[Mesh::ARRAY_VERTEX] && array[Mesh::ARRAY_VERTEX] != Variant()) {
const Vector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
int num_verts = vertices.size();

// The mesh contains invalid indices, abort.
ERR_FAIL_COND_V(!Geometry::verify_indices(inds.ptr(), inds.size(), num_verts), ERR_FILE_CORRUPT);
}
}

import_mesh->add_surface_from_arrays(primitive, array, morphs, p_state->compress_flags);
import_mesh->surface_set_material(mat_idx, mat);
}
Expand Down

0 comments on commit 3771078

Please sign in to comment.