Skip to content

A curve with a point that is not a number is not flattened without end - #38

Merged
timzifer merged 1 commit into
mainfrom
fix/nan-control-point
Oct 13, 2026
Merged

timzifer merged 1 commit into
mainfrom
fix/nan-control-point

Conversation

@timzifer

Copy link
Copy Markdown
Owner

The bug

Rasterizer.addQuad and addCubic (and the same two where a Shape records its edges) clamp the points of a curve that reaches beyond maxCoord and flatten it between the clamped points, by calling themselves. A point that is NaN stays NaN when it is clamped and still counts as beyond: the function called itself until the stack was used up.

That is a fatal error: stack overflow — it ends the process, and no recover of a caller catches it.

AddPath marks a path with such a point and drops it, but only after the curve was added. A point can be NaN as the path gives it, or become it under the matrix: a coordinate at infinity under a matrix with a zero in that place (a quarter turn) is 0·∞. A consumer that draws what a file says can be made to end this way.

The fix

A curve with a point that is not a number adds nothing (notNumbers), in all four places. The path is dropped as before.

Checked

  • TestCurveNotNumbers: a cubic and a quadratic with a NaN control point, and a cubic with one at infinity under a quarter turn — through Rasterizer.Fill, Canvas.Fill, Stroke, ClipPath, and Shape.SetFill/SetStroke with FillShape. Without the fix the test binary dies.
  • FuzzFill found it within seconds; with the fix it and FuzzStroke ran a minute each without a finding, on top of A pixel gets the same value in whatever region it is drawn #37.
  • The suite; staticcheck.

Wants a release: consumers are exposed until they take it.

addQuad and addCubic clamp the points of a curve that reaches beyond
maxCoord and flatten it between the clamped points. A point that is
NaN stays NaN when it is clamped, and still counts as beyond: the
function called itself until the stack was used up, which ends the
process — a fatal error, not a panic a caller could recover.

AddPath marks a path with such a point and drops it, but only after the
curve was added. A point of a path can be NaN as it is given, or become
it under the matrix: infinity turned by a quarter is 0·∞.

Such a curve now adds nothing, in the rasterizer and where a Shape
records its edges.
@timzifer timzifer added the bug Something isn't working label Oct 13, 2026
@timzifer
timzifer merged commit 3dbb871 into main Oct 13, 2026
13 checks passed
@timzifer
timzifer deleted the fix/nan-control-point branch October 13, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant