Repository navigation
test(api): cover a capsule bullet, hull and reader refusals - #356
Merged
Merged
Conversation
siracozmen01
commented
Nov 5, 2026
siracozmen01
left a comment
Collaborator
Author
There was a problem hiding this comment.
Review at 742e5d7: changes needed (2). Read, not run.
-
The equivalence claim for
count < 3does not hold, and one input tells the two apart.- In
ComputeHullWorker(geometry.c:319-342), the original refuses fewer than three points withm2_errorInvalidbefore any other check. - The mutant goes on to
m2CheckCountand thenPointsBoundsCheck, which answersm2_errorLimitfor a point or a radius pastM2_LOCAL_LIMIT. - So
m2ComputeHull(cloud, 2, 1e30f, &hull)ism2_errorInvalidon main andm2_errorLimitunder the mutant. So is two points with one at{1e30f, 0}. - For valid points with count 0, 1 or 2, the two do agree.
WeldPointskeeps at mostcountpoints, son < 3returnsm2_errorInvalid, and*polygonOutis written only on success. - Either add that two-point case with a far radius, if the header promises
m2_errorInvalidfor fewer than three points whatever else is wrong, or drop "no input tells the two apart" from the body, which becomes the commit message.
- In
-
The capsule bullet lands exactly on the wall's center without its sweep, so the test does not show tunneling.
- From x = -10 at 600 m/s, one step of 1/60 s (four substeps of 2.5 m, exact in double) ends at x = 0.0, the middle of the 0.1 m wall.
- Without the sweep, a discrete step therefore does not jump past the wall. It ends fully overlapped, and whether the body ends right or left of 0 then depends on which side the contact's normal picks at a symmetric overlap.
- The mutant failing today shows that tie went +x, not that the body passed through untouched. TestSegmentBulletStops has the same setup.
- Starting at, say, x = -9.8 puts the swept-less step at +0.2, wholly past the wall. Then
x < 0fails only by real tunneling.
What holds:
- "Output unchanged" is checked against a real sentinel, not zeros.
hullstarts asm2MakeBox(2, 2)(count 4, first vertex x = -2), and after the three refusals the test checkscount == 4 && vertices[0].x == -2.0f. A refusal that zeroed or rebuilt the output would fail it. It checks two fields, not the whole struct, but a partial write that kept both is not a plausible path, since the worker copies the wholem2Polygonor nothing. - The geometry readers: four wrong-type reads give zero and exactly four misuses, and the matching read counts none.
m2World_Validate(NULL)is false.
siracozmen01
commented
Nov 5, 2026
siracozmen01
left a comment
Collaborator
Author
There was a problem hiding this comment.
Delta 742e5d7..bc6eb3c: ready. Both findings are fixed. Read, not run.
m2ComputeHull(cloud, 2, 1.0e30f, &hull) == m2_errorInvalidis the input that tells thecount < 3check apart. Without it, the two points reachPointsBoundsCheck, and the radius pastM2_LOCAL_LIMITgivesm2_errorLimit. The "equivalent mutant" paragraph is gone from the body.TestCapsuleBulletStopsandTestSegmentBulletStopsstart at x = -9.8. One step of 10 m without the sweep lands at x = 0.2, wholly past the 0.1 m wall (its far face is at 0.05). Sox < 0fails only by real tunneling, and the comment and body say so. The capsule's 0.05 radius still leaves its near edge at 0.15, past the wall.
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.
Problem
A coverage run of main shows four paths a host can reach that no test takes: a capsule-only bullet's bounding radius,
m2ComputeHull's refusal of too little input, the geometry readers' type check, andm2World_Validatewith a null world. A change to any of them would pass every suite, and a capsule bullet with no bounding radius would tunnel (#355).Change
test/test_ccd.c:TestCapsuleBulletStops: a bullet whose only shape is a capsule, fired at 600 m/s, stops at a 0.1 m wall.TestSegmentBulletStopsstart at x = -9.8 instead of -10. One step moves them 10 m, so unswept they land at x = 0.2, past the wall. From -10 they landed exactly on the wall's center, so a skipped sweep failed only through the way a symmetric overlap resolves.test/test_shapes.c:TestHullRefusesTooLittle: a null cloud, two points and a null output are each refused withm2_errorInvalid, and leave the output as it was. So are two points with a radius of 1e30, which the point count refuses before the radius check would givem2_errorLimit. Three points make a triangle.TestGeometryReadersCheckTheType: the circle, polygon, capsule and segment readers on a shape of another type read zero and count one misuse each. The matching reader reads its shape and counts nothing.test/test_world.c, inTestValidateAndCounters:m2World_Validate(NULL)is false.A test-only change.
Verification
test_ccd,test_shapesandtest_worldpass.m2ComputeHulldoes not check for fewer than three pointsm2_errorLimit)m2ComputeHulldoes not check for a null cloudtest_shapescrashes on the null cloudm2World_Validatepasses a null worldtools/check.sh changedpasses. The changed files compile clean with gcc-14 and clang-20 under the strict flags.test_goldenprints the 13 lines oftest/hashes.txtunchanged in the scalar (linux-clang-20-asan) and AVX2 (linux-clang-20) presets.Closes #355