From acc18c197cdc45c58af2c5f1c082793e13675050 Mon Sep 17 00:00:00 2001 From: Roland Shum Date: Fri, 28 Aug 2026 15:35:10 -0700 Subject: [PATCH] Bounds-check sentinel and out-of-range indices in Validate() ValidateNoBowties used a vertex index equal to the unused-vertex sentinel index_t(-1) directly as the subscript faceIds[j] (faceIds sized nVerts). ValidateIndices allows the sentinel through, so it reached the bow-tie walk and indexed past the array. Skip it, as CleanImpl already does on the equivalent loop. Under VALIDATE_ASYMMETRIC_ADJ, find_edge read adjacency[k*3..+2] with an out-of-range k guarded only by assert(k < nFaces); in diagnostic-message mode the out-of-range value is recorded but does not stop processing, and the assert is elided under NDEBUG, so release builds had no check. Promote it to a runtime bound. --- DirectXMesh/DirectXMeshValidate.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/DirectXMesh/DirectXMeshValidate.cpp b/DirectXMesh/DirectXMeshValidate.cpp index bd9638a1..97bad5a4 100644 --- a/DirectXMesh/DirectXMeshValidate.cpp +++ b/DirectXMesh/DirectXMeshValidate.cpp @@ -201,7 +201,11 @@ namespace if (k == UNUSED32) continue; - assert(k < nFaces); + if (k >= nFaces) + { + result = false; + continue; + } const uint32_t edge = find_edge(&adjacency[k * 3], uint32_t(face)); if (edge >= 3) @@ -331,6 +335,8 @@ namespace faceSeen[curFace * 3 + curPoint] = true; uint32_t j = indices[curFace * 3 + curPoint]; + if (j == index_t(-1)) + continue; if (faceIds[j] == index_t(-1)) {