From f975b50f613fe429768f2717c310b9143e8212e2 Mon Sep 17 00:00:00 2001 From: "vs-code-engineering[bot]" <122617954+vs-code-engineering[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:53:43 +0000 Subject: [PATCH 1/2] fix: drop empty MessagePort frames instead of forwarding unparseable buffers (fixes #326171) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/vs/base/parts/ipc/common/ipc.mp.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.mp.ts b/src/vs/base/parts/ipc/common/ipc.mp.ts index 91931de0a326d..0e7dac69d1fec 100644 --- a/src/vs/base/parts/ipc/common/ipc.mp.ts +++ b/src/vs/base/parts/ipc/common/ipc.mp.ts @@ -44,12 +44,14 @@ export class Protocol implements IMessagePassingProtocol { readonly onMessage; constructor(private port: MessagePort) { - this.onMessage = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => { - if (e.data) { - return VSBuffer.wrap(e.data); - } - return VSBuffer.alloc(0); - }); + // A `message` event may carry no (or empty) data (e.g. during + // connection teardown). An empty frame is never a valid protocol + // message (the smallest valid frame still has a serialized header), + // so we must not forward it: doing so makes the channel readers + // deserialize an `undefined` header and crash. Filter these out at + // the transport boundary instead. + const onMessage = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => e.data ? VSBuffer.wrap(e.data) : undefined); + this.onMessage = Event.filter(onMessage, (data): data is VSBuffer => !!data && data.byteLength > 0); // we must call start() to ensure messages are flowing port.start(); } From bac22029739f112f7d4f8cb84bceb15ffe04ad6f Mon Sep 17 00:00:00 2001 From: "vs-code-engineering[bot]" <122617954+vs-code-engineering[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:51:32 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20Compile=20&=20Hygiene=20=E2=80=94=20?= =?UTF-8?q?resolve=20onMessage=20type=20by=20filtering=20empty=20frames=20?= =?UTF-8?q?on=20Event?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/vs/base/parts/ipc/common/ipc.mp.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.mp.ts b/src/vs/base/parts/ipc/common/ipc.mp.ts index 0e7dac69d1fec..c63ce5f5cd957 100644 --- a/src/vs/base/parts/ipc/common/ipc.mp.ts +++ b/src/vs/base/parts/ipc/common/ipc.mp.ts @@ -50,8 +50,8 @@ export class Protocol implements IMessagePassingProtocol { // so we must not forward it: doing so makes the channel readers // deserialize an `undefined` header and crash. Filter these out at // the transport boundary instead. - const onMessage = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => e.data ? VSBuffer.wrap(e.data) : undefined); - this.onMessage = Event.filter(onMessage, (data): data is VSBuffer => !!data && data.byteLength > 0); + const onMessage = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => e.data ? VSBuffer.wrap(e.data) : VSBuffer.alloc(0)); + this.onMessage = Event.filter(onMessage, data => data.byteLength > 0); // we must call start() to ensure messages are flowing port.start(); }