Skip to content

Commit

Permalink
Use string concatentation instead of spreading to prevent stack overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
kayahr committed Feb 4, 2024
1 parent fdd79ed commit 3a82edd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
24 changes: 12 additions & 12 deletions src/main/TextDecoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@ export class TextDecoder implements globalThis.TextDecoder {

// Decode the input bytes
const inputStream = new ByteBuffer(bytes);
const output = [];
let output = "";
let result: number | number[] | null;
while (!inputStream.isEndOfBuffer()) {
result = this.decoder.decode(inputStream);
if (result === FINISHED) {
break;
}
if (result != null) {
if (Array.isArray(result)) {
output.push(...result);
if (typeof result === "number") {
output += String.fromCodePoint(result);
} else {
output.push(result);
output += String.fromCodePoint(...result);
}
}
}
Expand All @@ -86,10 +86,10 @@ export class TextDecoder implements globalThis.TextDecoder {
break;
}
if (result != null) {
if (Array.isArray(result)) {
output.push(...result);
if (typeof result === "number") {
output += String.fromCodePoint(result);
} else {
output.push(result);
output += String.fromCodePoint(...result);
}
}
} while(!inputStream.isEndOfBuffer());
Expand All @@ -99,14 +99,14 @@ export class TextDecoder implements globalThis.TextDecoder {
// Remove BOM header from output if ignoreBOM flag is not set
if ([ "utf-8", "utf-16le", "utf-16be" ].includes(this.encoding) && !this.ignoreBOM && !this.seenBOM) {
if (output.length > 0) {
if (output[0] === 0xFEFF) {
output.shift();
}
this.seenBOM = true;
if (output[0] === "\uFEFF") {
return output.substring(1);
}
}
}

// Create and return string from decoded code points
return String.fromCodePoint(...output);
// Join the decoded code points into a full string and return it
return output;
}
}
8 changes: 8 additions & 0 deletions src/test/TextDecoder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,4 +328,12 @@ describe("TextDecoder", () => {
it("correctly maps 0xCA to U+05BA in windows-1255 encoding", () => {
expect(new TextDecoder("windows-1255").decode(new Uint8Array([ 0xca ]))).toBe("\u05BA");
});
it("correctly decodes a very large input", () => {
const data = new Uint16Array(1_000_000);
data.fill(0x5400);
const utf16 = new Uint8Array(data.buffer);
const decoded = new TextDecoder("utf-16be").decode(utf16);
expect(decoded.length).toBe(1_000_000);
expect(decoded).toContain("TTTT");
});
});

0 comments on commit 3a82edd

Please sign in to comment.