diff --git a/src/draco/javascript/emscripten/decoder_webidl_wrapper.cc b/src/draco/javascript/emscripten/decoder_webidl_wrapper.cc index 034f3c3b4..f9596ba01 100644 --- a/src/draco/javascript/emscripten/decoder_webidl_wrapper.cc +++ b/src/draco/javascript/emscripten/decoder_webidl_wrapper.cc @@ -175,7 +175,11 @@ template bool GetTrianglesArray(const draco::Mesh &m, const int out_size, T *out_values) { const uint32_t num_faces = m.num_faces(); - if (num_faces * 3 * sizeof(T) != out_size) { + // Check for integer overflow before size comparison. + const uint64_t required_size = + static_cast(num_faces) * 3 * sizeof(T); + if (required_size > static_cast(out_size) || + static_cast(required_size) != out_size) { return false; } diff --git a/src/draco/maya/draco_maya_plugin.cc b/src/draco/maya/draco_maya_plugin.cc index 25b0240b2..5fb027c18 100644 --- a/src/draco/maya/draco_maya_plugin.cc +++ b/src/draco/maya/draco_maya_plugin.cc @@ -20,6 +20,10 @@ namespace maya { static void decode_faces(std::unique_ptr &drc_mesh, Drc2PyMesh *out_mesh) { int num_faces = drc_mesh->num_faces(); + // Check for integer overflow in num_faces * 3. + if (num_faces < 0 || static_cast(num_faces) * 3 > SIZE_MAX / sizeof(int)) { + return; + } out_mesh->faces = new int[num_faces * 3]; out_mesh->faces_num = num_faces; for (int i = 0; i < num_faces; i++) { diff --git a/src/draco/unity/draco_unity_plugin.cc b/src/draco/unity/draco_unity_plugin.cc index e80279b89..61f2fe24a 100644 --- a/src/draco/unity/draco_unity_plugin.cc +++ b/src/draco/unity/draco_unity_plugin.cc @@ -236,6 +236,10 @@ bool EXPORT_API GetMeshIndices(const DracoMesh *mesh, DracoData **indices) { return false; } const Mesh *const m = static_cast(mesh->private_mesh); + // Check for integer overflow in num_faces * 3. + if (m->num_faces() > SIZE_MAX / 3 / sizeof(int)) { + return false; + } int *const temp_indices = new int[m->num_faces() * 3]; for (draco::FaceIndex face_id(0); face_id < m->num_faces(); ++face_id) { const Mesh::Face &face = m->face(draco::FaceIndex(face_id)); @@ -328,6 +332,11 @@ int DecodeMeshForUnity(char *data, unsigned int length, unity_mesh->num_faces = in_mesh->num_faces(); unity_mesh->num_vertices = in_mesh->num_points(); + // Check for integer overflow in num_faces * 3. + if (in_mesh->num_faces() > SIZE_MAX / 3 / sizeof(int)) { + ReleaseUnityMesh(&unity_mesh); + return -4; + } unity_mesh->indices = new int[in_mesh->num_faces() * 3]; for (draco::FaceIndex face_id(0); face_id < in_mesh->num_faces(); ++face_id) { const Mesh::Face &face = in_mesh->face(draco::FaceIndex(face_id)); @@ -336,6 +345,11 @@ int DecodeMeshForUnity(char *data, unsigned int length, } // TODO(draco-eng): Add other attributes. + // Check for integer overflow in num_points * components * sizeof(float). + if (in_mesh->num_points() > SIZE_MAX / 4 / sizeof(float)) { + ReleaseUnityMesh(&unity_mesh); + return -4; + } unity_mesh->position = new float[in_mesh->num_points() * 3]; const auto pos_att = in_mesh->GetNamedAttribute(draco::GeometryAttribute::POSITION);