Patch Manifold v3.5.2: fix a heap overflow in CsgLeafNode::Compose - #227
Merged
Merged
Conversation
CsgLeafNode::Compose calls RemoveDegenerates() on the combined mesh and then sorts it; on some inputs the cleanup leaves the face data inconsistent and GatherFaces reads past an array (heap-buffer-overflow under ASan, reached by MinkowskiDifference.ShrinksANonConvexBodyOnEverySide). Reproduced with Manifold alone and bisected upstream to #1789 (969b1417), which fixes it by deleting the same call; unreleased as of 3.5.4. Applied at fetch time by cmake/patch_manifold.cmake, which is idempotent and fails the configure if the source has moved on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 2, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug. Manifold v3.5.2 reads past the end of a heap array in
CsgLeafNode::Compose:Composecallscombined.RemoveDegenerates()and then sorts the mesh (SortGeometry→GatherFaces/ReindexFace).MinkowskiDifference.ShrinksANonConvexBodyOnEverySidereaches it, a holed plate eroded by a sphere. It fails under AddressSanitizer onmain. A normal build doesn't notice, which is why CI never has.Isolated and bisected upstream:
plate.MinkowskiDifference(sphere).mastercommits since v3.5.2's branch point. It's fixed by Improved decimation elalish/manifold#1789 "Improved decimation" (969b1417), which deletes that sameRemoveDegenerates()call. The rest of #1789 is a new decimator.master.masterisn't an option either. It removesCrossSection::FillRule, which we use in 8 places, and it has a separate regression: eroding a cube by a sphere returns an empty result.Change. FetchContent now runs
cmake/patch_manifold.cmakeas Manifold'sPATCH_COMMAND. The script deletes the call, re-runs as a no-op on already-patched source, and fails the configure if the code around the call has changed, so a version bump can't silently skip it. CLAUDE.md's Manifold entry records it and says to drop it once we move past #1789.Tested:
mainit aborts with the overflow).ctestpasses all 2013 tests.🤖 Generated with Claude Code