Skip to content

Commit

Permalink
Fix TextDecoder for SharedArrayBuffer backed TypedArray (denoland#1940)
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Mar 15, 2019
1 parent b2f15cf commit bb642e8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
13 changes: 11 additions & 2 deletions js/text_encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,13 @@ export interface TextDecoderOptions {
ignoreBOM?: false;
}

type EitherArrayBuffer = SharedArrayBuffer | ArrayBuffer;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isEitherArrayBuffer(x: any): x is EitherArrayBuffer {
return x instanceof SharedArrayBuffer || x instanceof ArrayBuffer;
}

export class TextDecoder {
private _encoding: string;

Expand Down Expand Up @@ -400,12 +407,14 @@ export class TextDecoder {
}

let bytes: Uint8Array;
if (typeof input === "object" && input instanceof ArrayBuffer) {
if (input instanceof Uint8Array) {
bytes = input;
} else if (isEitherArrayBuffer(input)) {
bytes = new Uint8Array(input);
} else if (
typeof input === "object" &&
"buffer" in input &&
input.buffer instanceof ArrayBuffer
isEitherArrayBuffer(input.buffer)
) {
bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
} else {
Expand Down
26 changes: 26 additions & 0 deletions js/text_encoding_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,29 @@ test(function textEncoder2() {
0xf0, 0x9d, 0x93, 0xbd
]);
});

test(function textDecoderSharedUint8Array() {
const ab = new SharedArrayBuffer(6);
const dataView = new DataView(ab);
const charCodeA = "A".charCodeAt(0);
for (let i = 0; i < ab.byteLength; i++) {
dataView.setUint8(i, charCodeA + i);
}
const ui8 = new Uint8Array(ab);
const decoder = new TextDecoder();
const actual = decoder.decode(ui8);
assertEquals(actual, "ABCDEF");
});

test(function textDecoderSharedInt32Array() {
const ab = new SharedArrayBuffer(8);
const dataView = new DataView(ab);
const charCodeA = "A".charCodeAt(0);
for (let i = 0; i < ab.byteLength; i++) {
dataView.setUint8(i, charCodeA + i);
}
const i32 = new Int32Array(ab);
const decoder = new TextDecoder();
const actual = decoder.decode(i32);
assertEquals(actual, "ABCDEFGH");
});

0 comments on commit bb642e8

Please sign in to comment.