-
Notifications
You must be signed in to change notification settings - Fork 17
Description
Summary
Hi! π
Firstly, thanks for your work on this project! π
The toArrayLike() method in react-native-bignumber crashes when called on a BigNumber representing zero. This occurs because the method creates a 0-length buffer and passes it to native code, which causes an immediate native crash.
Environment
- react-native-bignumber: 0.2.3
- Platform: React Native (iOS/Android) 0.74.7
- Impact: Critical - Native app crash
Problem Description
When toArrayLike() is called on a BigNumber with value 0:
this.byteLength()returns0outLenbecomes0- A 0-length buffer is created:
new ArrayType(0) - The 0-length buffer is passed to
native.toArrayLike.call() - Native code crashes attempting to work with empty buffer
Code Analysis
Current Implementation (Crashing)
Refer -
react-native-bignumber/src/BigNumber.ts
Line 229 in bf2703f
| toArrayLike<T extends (len: number) => { buffer: ArrayBuffer }>( |
toArrayLike(arrayLike, endian?, len?) {
const outLen = len != null ? len : this.byteLength(); // β Can be 0
const res = new (arrayLike as any)(outLen); // β Creates 0-length buffer
native.toArrayLike.call(
this.internalBigNum,
res.buffer, // β 0-length buffer crashes native code
endian === 'le',
len || -1
);
return res;
}Standard bn.js Implementation (Working)
Refer - https://github.com/indutny/bn.js/blob/6db7c3818569423b94ebcf2bdff90fcfb9c47f6d/lib/bn.js#L573
BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
var byteLength = this.byteLength();
var reqLength = length || Math.max(1, byteLength); // β
Ensures minimum 1 byte
var res = allocate(ArrayType, reqLength);
// ... pure JS implementation (no native crashes)
return res;
};Reproduction Steps
Minimal Reproduction
import { BN } from 'react-native-bignumber';
// Create a zero-valued BigNumber
const zeroBN = new BN(0);
// This should crash the app
const buffer = zeroBN.toArrayLike(Buffer); // π₯ CRASHReal-world Scenario (Solana Web3.js)
This issue was discovered when using Solana's web3.js library @solana/[email protected] in React Native. It uses bn.js but we have polyfilled it with react-native-bignumber
toBuffer(): Buffer {
const b = this._bn.toArrayLike(Buffer); // toArrayLike called here
if (b.length === PUBLIC_KEY_LENGTH) {
return b;
}
const zeroPad = Buffer.alloc(32);
b.copy(zeroPad, 32 - b.length);
return zeroPad;
}Impact: This makes Solana SOL transfers failures in React Native apps, as the Solana System Program ID 11111111111111111111111111111111 is required for all SOL transfer transactions.