Gathering detailed insights and metrics for @exodus/patch-broken-hermes-typed-arrays
Gathering detailed insights and metrics for @exodus/patch-broken-hermes-typed-arrays
Gathering detailed insights and metrics for @exodus/patch-broken-hermes-typed-arrays
Gathering detailed insights and metrics for @exodus/patch-broken-hermes-typed-arrays
Attempt to fix broken Hermes engine TypedArray implementation for React Native
npm install @exodus/patch-broken-hermes-typed-arrays
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1 Stars
23 Commits
2 Watching
1 Branches
59 Contributors
Updated on 04 Nov 2024
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
39.7%
88
Compared to previous day
Last week
44.8%
895
Compared to previous week
Last month
-22.5%
4,185
Compared to previous month
Last year
0%
12,009
Compared to previous year
@exodus/patch-broken-hermes-typed-arrays
Fix broken Hermes engine TypedArray implementation for React Native
Simply:
1import '@exodus/patch-broken-hermes-typed-arrays'
The problem behind this issue:
1> Buffer.alloc(10).subarray(0).toString('hex') 2'0,0,0,0,0,0,0,0,0,0' 3// What?
You might be inclined to fix the specific location where this is throwing (e.g. with a
Buffer.from
), but that is a mistake.
Most important: it is very hard to track all those.
Also, Buffer.from(arg)
is a copy and inefficiency,
Buffer.from(x.buffer, x.byteOffset, x.byteLength)
is awkward, prone to human errors and can
trigger security checks for doing something on buffer.buffer
manually (which is an unsafe
practice, e.g. a mistype like x.byteLegnth
can leak passwords/secrets to other users by exposing
unrelated application memory). You don't want a ton of copies of that pattern in your codebase.
Fixing this on Buffer
(e.g. by monkey-patching it) is also insufficient — your codebase could
include multiple dependencies which bundled buffer, and all
those instances won't be fixed that way!
Also, this affects more than Buffer
and more than subarray
— Hermes engine doesn't implement
TypedArray correctly.
i.e. Hermes implementation of TypedArray
doesn't follow these sections of the specification:
%TypedArray%.prototype.subarray
%TypedArray%.prototype.map
%TypedArray%.prototype.filter
%TypedArray%.prototype.slice
Overall, this module is just a glorified version of the following snippet (but with .map
/.filter
support and safeguards against Hermes updates, to detect if things change).
1TypedArray.prototype.subarray = function (...args) {
2 var arr = subarray.apply(this, args)
3 if (!this.constructor || arr.constructor === this.constructor) return arr
4 return new this.constructor(arr.buffer, arr.byteOffset, arr.length)
5}
Note: the above version might be not spec-compliant if Hermes implements resizable TypedArray
s
from ECMAScript 2024, or e.g. starts supporting Symbol.Species
Also the snippet above doesn't have a Hermes check, so it will also blindly patch arrays if you switch to JavaScriptCore
This is why this module exists — it handles all that
E.g. with buffer:
1// ... import Buffer polyfill from https://npmjs.com/package/buffer 2// ... and a console.log polyfill 3console.log(Buffer.alloc(2).subarray(0, 1).constructor.name) 4console.log(Buffer.alloc(2).map(() => 1).constructor.name) 5console.log(Buffer.alloc(2).filter(() => true).constructor.name)
1% node buftest.0.js 2Buffer 3Buffer 4Buffer 5% jsc buftest.0.js 6Buffer 7Buffer 8Buffer 9% hermes buftest.0.js 10Uint8Array 11Uint8Array 12Uint8Array
buffer
1// Let's assume this will get transpiled for a demo, Hermes has no `class` support 2 3class TestArray extends Uint16Array { 4 static instances = 0 5 constructor(...args) { 6 super(...args) 7 // console.log('We can do something here!') 8 TestArray.instances++ // count constructor calls 9 return this 10 } 11 12 hello() { 13 return 'hi there' 14 } 15} 16 17var arr = new TestArray(10) 18// TestArray.instances: 1 19 20var mapped = arr.map((_, i) => i * 10) 21// TestArray.instances: 2 22 23console.log(TestArray.instances) // 2 everywhere, but 1 in Hermes 24console.log(mapped.constructor.name) // 'TestArray' everywhere, but 'Uint16Array' in Hermes 25console.log(mapped.hello()) // throws in Hermes
See @exodus/test
No vulnerabilities found.
No security vulnerabilities found.