-
Notifications
You must be signed in to change notification settings - Fork 108
Fail if coords are outside of a safe range #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I still don't understand exactly why this constraint is getting violated, though. But fuzztester seems to find a lot of polylines that violate it, even without getting stuck in NaN-land. |
I think it is unrealistic that the algorithm is able to deal with max float. The issue with the large floats are that they quickly turn into infs, and then down the line either 0 or inf depending how they are used. The brittleness is in To get to the bottom of the issue, I think you should check what the s/t values are after projection, as well as what the sentinel edges are One solution could be to clamp the input points to a safe range. We should be able to figure out the sane range from |
For this particular example, the edge that violated that assert had:
That is, You're right that those sentinel edges are overflowing. The projection vectors for those are:
The code in
That seems equivalent to:
Are you suggesting clamping the values generated for the projection vectors in tessProjectPolygon? (Clamping to |
|
And I'd also guess that it might be better to fail in |
Made an attempt at this. It changes some of the previous test-cases to exit with error due to invalid input. |
Source/tess.c
Outdated
const TESSreal* coords = (const TESSreal*)src; | ||
src += stride; | ||
if (isnan(coords[0]) || isnan(coords[1]) || (size > 2 && isnan(coords[2]))) { | ||
if (isnan(coords[0]) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make the per component check a helper function.
I had bunch of pending comments from the other day, and did not realize that, sorry :) |
1f1bf71
to
fb0caef
Compare
Updated, please take a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few nags, should be trivial to fix. Other than that the implementation looks good.
The computation of sentinel edges in InitEdgeDict potentially overflows if coordinates are more than half of float max/min, and it distinguishes between real coord bounds and those sentinel edges by a 0.01 margin, which is not distinguishable at that magnitude due to loss-of-precision. That can cause assert failures in debug mode or uninitialized reads or crashes in optimized mode. Instead, fail if coordinates are not in `[-2^32, 2^32]`. This defines TESS_MAX_VALUE and TESS_MIN_VALUE in the public headers as those bounds, in case clients want to clamp or otherwise sanitize invalid inputs.
I messed up the range in the change description, the bounds are +/- 2^23, not 2^32. |
This avoids an assert-fail crash in debug mode, and reads of uninitialized memory and possibly crashes in optimized builds.