Skip to content

Fix heap-buffer-overflow in getCharts() for cross-chart vertices#17

Open
jdumas wants to merge 1 commit intomkazhdan:masterfrom
jdumas:fix-cross-chart-vertex-indexing
Open

Fix heap-buffer-overflow in getCharts() for cross-chart vertices#17
jdumas wants to merge 1 commit intomkazhdan:masterfrom
jdumas:fix-cross-chart-vertex-indexing

Conversation

@jdumas
Copy link
Copy Markdown

@jdumas jdumas commented Apr 9, 2026

Summary

  • Fix out-of-bounds read in AtlasChart::vertex() when atlas mesh vertices are shared between different UV charts (pinch points)
  • The getCharts() function used a single flat chartVertexID map that incorrectly reused local vertex indices across charts
  • Add a parallel chartVertexChart vector to track which chart each vertex was assigned to

Details

The bug occurs when AtlasMesh::initialize() deduplicates texture vertices by (UV position, surface vertex index). Two texture vertices at a UV seam pinch point with the same position and same surface vertex get merged into one atlas mesh vertex, even though they belong to different charts (computed via edge connectivity in trianglesToComponents).

In getCharts(), the global chartVertexID[v] is set by the first chart that encounters vertex v. When a second chart encounters the same vertex, it skips adding it and reuses the first chart's local index, which is meaningless for the second chart's vertex array, causing an out-of-bounds access.

Found using AddressSanitizer on a mesh with UV pinch points.

The `getCharts()` function in `AtlasCharts.inl` uses a flat
`chartVertexID` vector to map atlas mesh vertex indices to chart-local
vertex indices. When an atlas mesh vertex is shared between two UV
charts (a "pinch point" — same UV position and same surface vertex at a
seam), the first chart sets `chartVertexID[v]` to its local index. The
second chart then skips adding the vertex and reuses the first chart's
local index, which is invalid for the second chart's vertex array.

This causes an out-of-bounds read in `AtlasChart::vertex()` when the
second chart later accesses its (smaller) vertex vector with an index
that belongs to the first chart.

The fix adds a parallel `chartVertexChart` vector to track which chart
each vertex was last assigned to. When a vertex is encountered in a
different chart, it is re-added to the new chart with a fresh local
index.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant