Skip to content

Commit edb4a20

Browse files
committed
fix: support cross-context ArrayBuffer in TextDecoder
1 parent a576685 commit edb4a20

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

fallback/encoding.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,18 @@ export function normalizeEncoding(label) {
4747

4848
const define = (obj, key, value) => Object.defineProperty(obj, key, { value, writable: false })
4949

50+
function isAnyArrayBuffer(x) {
51+
if (!x || typeof x.byteLength !== 'number') return false
52+
const s = Object.prototype.toString.call(x)
53+
return s === '[object ArrayBuffer]' || s === '[object SharedArrayBuffer]'
54+
}
55+
5056
const fromSource = (x) => {
5157
if (x instanceof Uint8Array) return x
5258
if (x instanceof ArrayBuffer) return new Uint8Array(x)
5359
if (ArrayBuffer.isView(x)) return new Uint8Array(x.buffer, x.byteOffset, x.byteLength)
5460
if (globalThis.SharedArrayBuffer && x instanceof SharedArrayBuffer) return new Uint8Array(x)
61+
if (isAnyArrayBuffer(x)) return new Uint8Array(x)
5562
throw new TypeError('Argument must be a SharedArrayBuffer, ArrayBuffer or ArrayBufferView')
5663
}
5764

tests/encoding/cross-context.test.cjs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,29 @@ try {
1111
describe('vm', { skip: !vm }, () => {
1212
const string = 'Hello, \u2200'
1313
const u = Uint8Array.of(0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0xe2, 0x88, 0x80)
14+
const ctx = { TextDecoder, TextEncoder }
1415

1516
test('TextEncoder', (t) => {
16-
const ctx = { TextEncoder }
1717
const outer = new TextEncoder().encode(string)
1818
const inner = vm.runInNewContext(`new TextEncoder().encode(${JSON.stringify(string)})`, ctx)
1919
t.assert.deepStrictEqual(outer, u)
2020
t.assert.deepStrictEqual(inner, u)
2121
})
2222

23-
test('TextDecoder', (t) => {
24-
const ctx = { TextDecoder }
23+
test('TextDecoder + Uint8Array', (t) => {
2524
const outer = new TextDecoder().decode(u)
2625
const inner = vm.runInNewContext(`new TextDecoder().decode(Uint8Array.of(${u.join(',')}))`, ctx)
2726
t.assert.deepStrictEqual(outer, string)
2827
t.assert.deepStrictEqual(inner, string)
2928
})
29+
30+
test('TextDecoder + ArrayBuffer', (t) => {
31+
const outer = new TextDecoder().decode(u.buffer)
32+
const inner = vm.runInNewContext(
33+
`new TextDecoder().decode(Uint8Array.of(${u.join(',')}).buffer)`,
34+
ctx
35+
)
36+
t.assert.deepStrictEqual(outer, string)
37+
t.assert.deepStrictEqual(inner, string)
38+
})
3039
})

0 commit comments

Comments
 (0)