From 1943636f023b0496c2b95aeb31f2d08d7c0e4dce Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:14:22 -0800 Subject: [PATCH] Help embedders avoid memory leaks by clearing options Related microsoft/vscode#192838 --- src/browser/Linkifier2.ts | 3 +++ src/common/services/OptionsService.ts | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/browser/Linkifier2.ts b/src/browser/Linkifier2.ts index 28002e04d2..f7b1f605eb 100644 --- a/src/browser/Linkifier2.ts +++ b/src/browser/Linkifier2.ts @@ -39,6 +39,9 @@ export class Linkifier2 extends Disposable implements ILinkifier2 { this.register(getDisposeArrayDisposable(this._linkCacheDisposables)); this.register(toDisposable(() => { this._lastMouseEvent = undefined; + // Clear out link providers as they could easily cause an embedder memory leak + this._linkProviders.length = 0; + this._activeProviderReplies?.clear(); })); // Listen to resize to catch the case where it's resized and the cursor is out of the viewport. this.register(this._bufferService.onResize(() => { diff --git a/src/common/services/OptionsService.ts b/src/common/services/OptionsService.ts index eb9dbfa8c2..ba92992e9f 100644 --- a/src/common/services/OptionsService.ts +++ b/src/common/services/OptionsService.ts @@ -4,7 +4,7 @@ */ import { EventEmitter } from 'common/EventEmitter'; -import { Disposable } from 'common/Lifecycle'; +import { Disposable, toDisposable } from 'common/Lifecycle'; import { isMac } from 'common/Platform'; import { CursorStyle, IDisposable } from 'common/Types'; import { FontWeight, IOptionsService, ITerminalOptions } from 'common/services/Services'; @@ -86,6 +86,13 @@ export class OptionsService extends Disposable implements IOptionsService { this.rawOptions = defaultOptions; this.options = { ... defaultOptions }; this._setupOptions(); + + // Clear out options that could link outside xterm.js as they could easily cause an embedder + // memory leak + this.register(toDisposable(() => { + this.rawOptions.linkHandler = null; + this.rawOptions.documentOverride = null; + })); } // eslint-disable-next-line @typescript-eslint/naming-convention