From 465759bc5855192aaa57ff09de70dd28f4ddf3ca Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 11 Jun 2021 06:45:36 -0700 Subject: [PATCH] Prevent other extensions registering terminal profiles --- .../api/browser/mainThreadTerminalService.ts | 8 +++++--- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostTerminalService.ts | 6 +++--- .../contrib/terminal/browser/terminal.ts | 4 ++-- .../terminal/browser/terminalService.ts | 20 ++++++++++++------- .../contrib/terminal/browser/terminalView.ts | 4 ++-- .../common/terminalExtensionPoints.ts | 6 +++--- 8 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 7b52f5c75d1..d9e9523de37 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -211,10 +211,12 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._terminalService.registerProcessSupport(isSupported); } - public $registerProfileProvider(id: string): void { + public $registerProfileProvider(id: string, extensionIdentifier: string): void { // Proxy profile provider requests through the extension host - this._profileProviders.set(id, this._terminalService.registerTerminalProfileProvider(id, { - createContributedTerminalProfile: async (isSplitTerminal) => this._proxy.$createContributedProfileTerminal(id, isSplitTerminal) + this._profileProviders.set(id, this._terminalService.registerTerminalProfileProvider(extensionIdentifier, id, { + createContributedTerminalProfile: async (isSplitTerminal) => { + return this._proxy.$createContributedProfileTerminal(id, isSplitTerminal); + } })); } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 34723811671..f24fc12689f 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -675,7 +675,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostTerminalService.registerLinkProvider(provider); }, registerTerminalProfileProvider(id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable { - return extHostTerminalService.registerProfileProvider(id, provider); + return extHostTerminalService.registerProfileProvider(extension, id, provider); }, registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider): vscode.Disposable { return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index f93362a38f0..568a235420d 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -486,7 +486,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable { $startLinkProvider(): void; $stopLinkProvider(): void; $registerProcessSupport(isSupported: boolean): void; - $registerProfileProvider(id: string): void; + $registerProfileProvider(id: string, extensionIdentifier: string): void; $unregisterProfileProvider(id: string): void; $setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: ISerializableEnvironmentVariableCollection | undefined): void; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index b9a8f43505a..a28ff3647c8 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -43,7 +43,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID getDefaultShell(useAutomationShell: boolean): string; getDefaultShellArgs(useAutomationShell: boolean): string[] | string; registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable; - registerProfileProvider(id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable; + registerProfileProvider(extension: IExtensionDescription, id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable; getEnvironmentVariableCollection(extension: IExtensionDescription, persistent?: boolean): vscode.EnvironmentVariableCollection; } @@ -584,12 +584,12 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I }); } - public registerProfileProvider(id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable { + public registerProfileProvider(extension: IExtensionDescription, id: string, provider: vscode.TerminalProfileProvider): vscode.Disposable { if (this._profileProviders.has(id)) { throw new Error(`Terminal profile provider "${id}" already registered`); } this._profileProviders.set(id, provider); - this._proxy.$registerProfileProvider(id); + this._proxy.$registerProfileProvider(id, extension.identifier.value); return new VSCodeDisposable(() => { this._profileProviders.delete(id); this._proxy.$unregisterProfileProvider(id); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 31cac615fef..33932d8a39b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -141,7 +141,7 @@ export interface ITerminalService { */ createTerminal(profile: ITerminalProfile): ITerminalInstance; - createContributedTerminalProfile(id: string, isSplitTerminal: boolean): Promise; + createContributedTerminalProfile(extensionIdentifier: string, id: string, isSplitTerminal: boolean): Promise; /** * Creates a raw terminal instance, this should not be used outside of the terminal part. @@ -201,7 +201,7 @@ export interface ITerminalService { */ registerLinkProvider(linkProvider: ITerminalExternalLinkProvider): IDisposable; - registerTerminalProfileProvider(id: string, profileProvider: ITerminalProfileProvider): IDisposable; + registerTerminalProfileProvider(extensionIdenfifier: string, id: string, profileProvider: ITerminalProfileProvider): IDisposable; showProfileQuickPick(type: 'setDefault' | 'createInstance', cwd?: string | URI): Promise; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 8cfc0e816fd..69c29005c37 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -57,7 +57,7 @@ export class TerminalService implements ITerminalService { private _findState: FindReplaceState; private _activeGroupIndex: number; private _activeInstanceIndex: number; - private readonly _profileProviders: Map = new Map(); + private readonly _profileProviders: Map> = new Map(); private _linkProviders: Set = new Set(); private _linkProviderDisposables: Map = new Map(); private _processSupportContextKey: IContextKey; @@ -811,8 +811,13 @@ export class TerminalService implements ITerminalService { }; } - registerTerminalProfileProvider(id: string, profileProvider: ITerminalProfileProvider): IDisposable { - this._profileProviders.set(id, profileProvider); + registerTerminalProfileProvider(extensionIdenfifier: string, id: string, profileProvider: ITerminalProfileProvider): IDisposable { + let extMap = this._profileProviders.get(extensionIdenfifier); + if (!extMap) { + extMap = new Map(); + this._profileProviders.set(extensionIdenfifier, extMap); + } + extMap.set(id, profileProvider); return toDisposable(() => this._profileProviders.delete(id)); } @@ -976,7 +981,7 @@ export class TerminalService implements ITerminalService { let instance; if ('id' in value.profile) { - await this.createContributedTerminalProfile(value.profile.id, !!(keyMods?.alt && activeInstance)); + await this.createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, !!(keyMods?.alt && activeInstance)); return; } else { if (keyMods?.alt && activeInstance) { @@ -1017,9 +1022,10 @@ export class TerminalService implements ITerminalService { return undefined; } - async createContributedTerminalProfile(id: string, isSplitTerminal: boolean): Promise { + async createContributedTerminalProfile(extensionIdentifier: string, id: string, isSplitTerminal: boolean): Promise { await this._extensionService.activateByEvent(`onTerminalProfile:${id}`); - const profileProvider = this._profileProviders.get(id); + const extMap = this._profileProviders.get(extensionIdentifier); + const profileProvider = extMap?.get(id); if (!profileProvider) { this._notificationService.error(`No terminal profile provider registered for id "${id}"`); return; @@ -1207,7 +1213,7 @@ export class TerminalService implements ITerminalService { } interface IProfileQuickPickItem extends IQuickPickItem { - profile: ITerminalProfile | ITerminalProfileContribution; + profile: ITerminalProfile | (ITerminalProfileContribution & { extensionIdentifier: string }); } interface IInstanceLocation { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index 6f28f55ae73..cdb7e78c3ae 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -227,8 +227,8 @@ export class TerminalViewPane extends ViewPane { } for (const contributed of this._terminalContributionService.terminalProfiles) { - dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title, undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.id, false))); - submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title, undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.id, true))); + dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title, undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, false))); + submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title, undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, true))); } if (dropdownActions.length > 0) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts b/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts index 7aaf52ce172..77370d574ca 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalExtensionPoints.ts @@ -14,7 +14,7 @@ export const terminalsExtPoint = extensionsRegistry.ExtensionsRegistry.registerE export interface ITerminalContributionService { readonly _serviceBrand: undefined; - readonly terminalProfiles: ReadonlyArray; + readonly terminalProfiles: ReadonlyArray; } export const ITerminalContributionService = createDecorator('terminalContributionsService'); @@ -22,7 +22,7 @@ export const ITerminalContributionService = createDecorator = []; + private _terminalProfiles: ReadonlyArray = []; get terminalProfiles() { return this._terminalProfiles; } constructor() { @@ -36,7 +36,7 @@ export class TerminalContributionService implements ITerminalContributionService } else { e.icon = undefined; } - return e; + return { ...e, extensionIdentifier: c.description.identifier.value }; }) || []; })); });