bignumber.js: Infinite loop in Safari 10.1

There appears to be an infinite loop in https://github.com/MikeMcl/bignumber.js/blob/46ed093a78e4061efeac50c1bbae624ad61a33f2/bignumber.js#L918-L925 for new versions of Webkit, including the newly released Safari 10.1

(new BigNumber(2043150)).dividedBy(10000);

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 48 (19 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve published v4.0.2 which uses Jamie’s above workaround to resolve this issue. Thank you to all contributors.

Amazing! Thanks for diligent testing @dfrencham 💯

Your isolation of failing tests lead me to discover that the .unshift() method is also affected. I’ve yet to find exact code to replicate the bug, but changing the unshift here to an alternative allowed base-out tests to pass. Changing the rest fixed the test suite.

I’ve added a workaround to my fork using Array.prototype.concat to mimic unshift. The tests now ALL PASS on Safari 10.1 for myself locally 🎉 . Are you able to confirm validity of tests? 😄

These workarounds have probably slowed the performance down a little as native shift/unshift will be faster.

The failing test suites above worry me greatly. I think it’s safe to assume that if you’re using bignumber.js in your app or library and have users on latest stable iOS/Safari browsers any calculations in the last 30ish days could be inaccurate… 😱

I logged it as a webkit bug here: https://bugs.webkit.org/show_bug.cgi?id=170264

+1’s on the bug ticket would be appreciated (add a comment and say you’re seeing the same behaviour).

thank you. it bugs in the browser. Array#shift

var arr = [0, 2147483648];
arr.shift(); // arr is [2147483648]
arr[1] = 1; // arr is [2147483648, 1]
console.log(arr); // arr is [2147483648, 1], but [2147483648] in Safari 10.1

(smaller 2147483647, it works collectly.)

var arr = [0, 2147483647];
arr.shift(); // arr is [2147483647]
arr[1] = 1; // arr is [2147483647, 1]
console.log(arr); // arr is [2147483647, 1] in all browsers.

fix to bug

var arr = [0, 2147483648];
arr.shift();
arr = arr.slice(); // fix to bug
arr[1] = 1;
console.log(arr); // arr is [2147483648, 1]

I’ll trying report to Apple.

I implemented the workaround I suggested in my fork. You could use it as a temporary workaround

https://github.com/Ka0o0/bignumber.js

@krachtstefan

It’s v4.0.2 and I’ve just pushed the tag now. Thanks for the reminder.

@jamsinclair all tests are passing here mate. The failing tests are a bit of a worry, we count our user base in the millions, with a significant percentage using IOS.

@MikeMcl thanks for pushing that through, much appreciated!

Mimicking shift via splice seems to work in affected Apple browsers:

var arr = [0, 2147483648]; 
arr.splice(0, 1);
arr[1] = 1;

// This will evaluate true in Safari and is expected
expect(arr).toEqual([2147483648, 1])

@MikeMcl I understand you’d rather have this issue resolved by Apple, but after 30 day it seems in limbo whether this is happening soon.

I have a fork and PR here #122. Should hopefully allow reliable calculations with bignumber.js in affected Apple browsers.

Let me know if I can make any changes or help 😄

Edit Update

The browser test /test/browser/every-test.html fails and hangs in Safari 10.1 with and without my change 😢

All tests pass with Safari Preview 10.2 and the rest of the browser gang (Chrome, FF, Opera, Edge)

Anyone able to confirm/replicate this?

Looks like the webkit bug maybe affecting the library in other ways than just the .shift() hypothesis.