Skip to content

Commit 806bbc7

Browse files
committed
fix(browser): keep UTF-8 stderr tails valid
1 parent 9566ade commit 806bbc7

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

extensions/browser/src/browser/bounded-utf8-tail.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ describe("bounded UTF-8 tail", () => {
1616
expect(decodeBoundedUtf8Tail(encoded, 5)).toBe("new");
1717
});
1818

19+
it("drops a partial trailing code point after byte truncation", () => {
20+
const encoded = Buffer.from([0xf0, 0x9f, 0x98, 0x80]);
21+
22+
expect(decodeBoundedUtf8Tail(encoded, 1)).toBe("");
23+
});
24+
1925
it("replaces the retained tail when one chunk fills the limit", () => {
2026
const tail = createBoundedUtf8Tail(4);
2127
tail.append("old");
@@ -34,4 +40,16 @@ describe("bounded UTF-8 tail", () => {
3440

3541
expect(tail.text()).toBe("test");
3642
});
43+
44+
it("waits for split UTF-8 code points before decoding them", () => {
45+
const tail = createBoundedUtf8Tail(4);
46+
const encoded = Buffer.from([0xf0, 0x9f, 0x98, 0x80]);
47+
tail.append(encoded.subarray(0, 1));
48+
49+
expect(tail.text()).toBe("");
50+
51+
tail.append(encoded.subarray(1));
52+
53+
expect(tail.text()).toBe("\u{1f600}");
54+
});
3755
});

extensions/browser/src/browser/bounded-utf8-tail.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/** Byte-bounded UTF-8 tail storage for browser subprocess diagnostics. */
2+
import { StringDecoder } from "node:string_decoder";
23

34
function decodeUtf8Tail(buffer: Buffer): string {
45
let start = 0;
56
while (start < buffer.length && (buffer[start]! & 0b1100_0000) === 0b1000_0000) {
67
start += 1;
78
}
8-
return buffer.subarray(start).toString("utf8");
9+
return new StringDecoder("utf8").write(buffer.subarray(start));
910
}
1011

1112
export function decodeBoundedUtf8Tail(buffer: Buffer, maxBytes: number): string {

0 commit comments

Comments
 (0)