Skip to content

compute_average_mesh_edge_length: out-of-bounds read and divide-by-zero for an empty mesh (num_tris == 0) #1602

Description

@EylonKrause

Describe the bug

compute_average_mesh_edge_length in warp/native/mesh.cu unconditionally indexes sum_edge_lengths[n - 1] and divides by 3 * n:

__global__ void compute_average_mesh_edge_length(int n, float* sum_edge_lengths, Mesh* m)
{
    m->average_edge_length = sum_edge_lengths[n - 1] / (3 * n);
}

For an empty mesh (n == 0, i.e. no triangles), this reads sum_edge_lengths[-1] — an out-of-bounds device read (and sum_edge_lengths may itself be a zero-length / null buffer) — and divides by zero, producing a NaN average_edge_length, which is then used as the welding epsilon.

Location

warp/native/mesh.cu, compute_average_mesh_edge_length (≈ lines 57–60).

Reachability

Constructing a wp.Mesh with empty indices on a CUDA device.

Suggested fix

Guard the empty case — either skip the three launches when num_tris == 0 on the host side, or in-kernel:

m->average_edge_length = (n > 0) ? sum_edge_lengths[n - 1] / (3.0f * n) : 0.0f;

This removes the out-of-bounds read and the divide-by-zero, and aligns the CUDA path with the CPU path for a degenerate (empty) mesh.

Note on verification

Found by static analysis; I don't have a Warp build locally, so I have not reproduced the OOB at runtime. A maintainer could confirm by creating a wp.Mesh with empty indices on CUDA under compute-sanitizer --tool memcheck. Filing in case it's useful; happy to open a PR if the suggested fix looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions