Skip to content

fix infinite loop in numAxisSplits for big-magnitude flat ranges - #1142

Open
cpruijsen wants to merge 1 commit into
leeoniya:masterfrom
cpruijsen:fix/issue-827
Open

fix infinite loop in numAxisSplits for big-magnitude flat ranges#1142
cpruijsen wants to merge 1 commit into
leeoniya:masterfrom
cpruijsen:fix/issue-827

Conversation

@cpruijsen

Copy link
Copy Markdown

numAxisSplits in src/opts.js can hang the page. Its loop advances with
val = roundDec(val + foundIncr, numDec), and when numDec is too small for the increment, the
rounded result comes back equal to the previous val. The condition val <= scaleMax stays true
forever and the tab locks up rather than rendering a wrong axis.

Two changes, in the order the failure happens.

numIntDigits in src/utils.js computed the digit count with the branchless int32 absolute value
(x ^ (x >> 31)) - (x >> 31). Both shifts coerce to a signed 32 bit integer, so any magnitude at or
above 2^31 wraps and the digit count comes back wrong, which is what produces the numDec that
cannot represent the increment. It now takes abs(x) and only truncates with | 0 while the value
is inside int32 range, using the float directly above it.

The loop then carries a prevVal guard and stops when a step fails to advance. That is a backstop
rather than the fix: with the digit count corrected the loop terminates on its own, but a stalled
step should end the loop rather than the session, since the remaining causes of a non advancing step
are floating point ones that are hard to enumerate.

Fixes #827

numIntDigits() wrapped to int32 for |x| >= 2^31, so findIncr's
significant-digits guard under-counted the magnitude and could pick
a sub-ULP foundIncr (e.g. 1e-8 at 1e14) that can never advance val
in the numAxisSplits loop, hanging the browser.

- numIntDigits: use log10(abs(x)) outside the int32 fast range
- numAxisSplits: require val to strictly increase each iteration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Infinite loop in numAxisSplits

1 participant