fix: close Θ-W7-T1 round-2 leftovers — NaN guard placement, comment attribution, CLAUDE.md export

Moves the NaN/Inf finiteness check to addSegment where the UB-causing cast actually happens, makes strokeBounds reject an interior non-finite point instead of swallowing it, corrects a LICE_GetPixel misattribution, and documents rasterRowOffset.
This commit is contained in:
2026-08-01 13:59:09 -04:00
parent 3fb77027c6
commit 07628a2059
4 changed files with 51 additions and 18 deletions
+29 -2
View File
@@ -289,6 +289,31 @@ static void testCoverageOutsideTheValidSpanReadsZero() {
CHECK(c.coverageAt(1000, 1000) == 0.0f);
}
// --- non-finite input rejection ------------------------------------------------
static void testInteriorNonFiniteCoordinateRejectsTheWholeStroke() {
// Only pts[0] going non-finite used to propagate through strokeBounds's min/max reduction:
// std::min/max against NaN silently returns the OTHER, finite, operand, so a NaN anywhere
// else in the polyline vanished from the reduction instead of rejecting it. pts[1] here is
// the case that check missed.
const StrokePoint pts[3] = {{10.0f, 10.0f}, {NAN, 50.0f}, {90.0f, 10.0f}};
CHECK(strokeBounds(pts, 3, 1.5f, kBig).empty());
StrokeCanvas c;
strokePolyline(c, pts, 3, 1.5f, kBig);
CHECK(c.bounds().empty());
}
static void testAddSegmentRejectsNonFiniteInputsDirectly() {
// addSegment casts a pieces-count derived from len2 to int; a NaN/Inf endpoint must be
// caught before that cast, not one call layer down in addPiece where it's already too late.
StrokeCanvas c;
c.reset(kBig);
c.addSegment(10.0f, 10.0f, NAN, 50.0f, 1.5f);
c.addSegment(10.0f, 10.0f, INFINITY, 50.0f, 1.5f);
CHECK(peakCoverage(c) == 0.0f);
}
// --- raster row addressing ----------------------------------------------------
static void testRasterRowOffsetMatchesUnflippedAndFlippedLayouts() {
@@ -296,8 +321,8 @@ static void testRasterRowOffsetMatchesUnflippedAndFlippedLayouts() {
CHECK(rasterRowOffset(0, 100, 240, false) == 0u);
CHECK(rasterRowOffset(5, 100, 240, false) == 5u * 240u);
CHECK(rasterRowOffset(99, 100, 240, false) == 99u * 240u);
// Flipped (bottom-up DIBs): row y is (height-1-y)*rowSpan — LICE_SysBitmap's own pixel
// accessor, `(h-1-y)*rowspan + x` (lice.cpp:2262).
// Flipped (bottom-up DIBs): row y is (height-1-y)*rowSpan — matches the free function
// LICE_GetPixel's own row math, `(h-1-y)*rowspan + x` (lice.cpp:2262).
CHECK(rasterRowOffset(0, 100, 240, true) == 99u * 240u);
CHECK(rasterRowOffset(99, 100, 240, true) == 0u);
CHECK(rasterRowOffset(40, 100, 240, true) == 59u * 240u);
@@ -441,6 +466,8 @@ int main() {
testBoundsClipToTheClipRectAndCoverTheReach();
testStrokeEntirelyOutsideTheClipDrawsNothing();
testCoverageOutsideTheValidSpanReadsZero();
testInteriorNonFiniteCoordinateRejectsTheWholeStroke();
testAddSegmentRejectsNonFiniteInputsDirectly();
testRasterRowOffsetMatchesUnflippedAndFlippedLayouts();
testSubdivisionDoesNotChangeTheRenderedStroke();
testArcPointsLieOnTheCircleAndRespectTheFlatness();