facebook / facebook/hermes

TypedArrays are not spec-compliant and break Buffer with many ecosystem packages

Open
#1,495 10 comments 8 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
11.3k
Forks
859
Avg merge
1h 30m
Merged PRs (30d)
3

Description

## Bug Description

### See explainer, test and a monkey-patch fix at https://github.com/ExodusMovement/patch-broken-hermes-typed-arrays

```js
> Buffer.alloc(10).subarray(0).toString('hex')
'0,0,0,0,0,0,0,0,0,0'
// What?
```

Sections of specification broken in Hermes:
* [ECMAScript® Language Specification, `%TypedArray%.prototype.subarray`](https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray)
* [ECMAScript® Language Specification, `%TypedArray%.prototype.map`](https://tc39.es/ecma262/#sec-%typedarray%.prototype.map)
* [ECMAScript® Language Specification, `%TypedArray%.prototype.filter`](https://tc39.es/ecma262/#sec-%typedarray%.prototype.filter)
* [ECMAScript® Language Specification, `%TypedArray%.prototype.slice`](https://tc39.es/ecma262/#sec-%typedarray%.prototype.slice)

See https://github.com/ExodusMovement/patch-broken-hermes-typed-arrays/blob/main/index.js for links to specific spec steps

See ecosystem fallout in https://github.com/feross/buffer/issues/329

- [x] I ~have run `gradle clean` and~ confirmed this bug does not occur with JSC
- [x] The issue is reproducible with the latest version of ~React Native.~ Hermes

Hermes git revision (if applicable): 0410fb4 (latest `main`)
React Native version: 🤷🏻
OS:
Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64):

## Steps To Reproduce

See full explainer, test and a monkey-patch fix at https://github.com/ExodusMovement/patch-broken-hermes-typed-arrays

```console
chalker@Nikitas-Air hermes_workingdir % cat bad-inheritance.js
var TestArray = function (...args) {
print('called TestArray constructor')
var buf = new Uint8Array(...args)
Object.setPrototypeOf(buf, TestArray.prototype)
return buf
}

Object.setPrototypeOf(TestArray.prototype, Uint8Array.prototype)
Object.setPrototypeOf(TestArray, Uint8Array)

var arr = new TestArray(10)
var mapped = arr.map((_, i) => i * 10)
print(mapped.constructor.name)
chalker@Nikitas-Air hermes_workingdir % jsc bad-inheritance.js
called TestArray constructor
called TestArray constructor
TestArray
chalker@Nikitas-Air hermes_workingdir % ./build_release/bin/hermes bad-inheritance.js
called TestArray constructor
Uint8Array
```

## The Expected Behavior

Implementation of TypedArray per spec, perhaps without `Symbol.species` but with working inheritance

See spec refs above

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.