Skip to content

Commit

Permalink
Ensure remote backend command requests are only executed once
Browse files Browse the repository at this point in the history
Fixes #121926
  • Loading branch information
Tyriar committed Aug 19, 2022
1 parent 4ec47f2 commit 677b083
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
15 changes: 8 additions & 7 deletions src/vs/server/node/remoteTerminalChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
uriTransformer: IURITransformer;
}>();

private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; commandId: string; commandArgs: any[] }>());
private readonly _onExecuteCommand = this._register(new Emitter<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>());
readonly onExecuteCommand = this._onExecuteCommand.event;

constructor(
Expand Down Expand Up @@ -240,21 +240,21 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
// Setup the CLI server to support forwarding commands run from the CLI
const ipcHandlePath = createRandomIPCHandle();
env.VSCODE_IPC_HOOK_CLI = ipcHandlePath;

const persistentProcessId = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
const commandsExecuter: ICommandsExecuter = {
executeCommand: <T>(id: string, ...args: any[]): Promise<T> => this._executeCommand(id, args, uriTransformer)
executeCommand: <T>(id: string, ...args: any[]): Promise<T> => this._executeCommand(persistentProcessId, id, args, uriTransformer)
};
const cliServer = new CLIServerBase(commandsExecuter, this._logService, ipcHandlePath);

const id = await this._ptyService.createProcess(shellLaunchConfig, initialCwd, args.cols, args.rows, args.unicodeVersion, env, baseEnv, args.options, args.shouldPersistTerminal, args.workspaceId, args.workspaceName);
this._ptyService.onProcessExit(e => e.id === id && cliServer.dispose());
this._ptyService.onProcessExit(e => e.id === persistentProcessId && cliServer.dispose());

return {
persistentTerminalId: id,
persistentTerminalId: persistentProcessId,
resolvedShellLaunchConfig: shellLaunchConfig
};
}

private _executeCommand<T>(commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
private _executeCommand<T>(persistentProcessId: number, commandId: string, commandArgs: any[], uriTransformer: IURITransformer): Promise<T> {
let resolve!: (data: any) => void;
let reject!: (err: any) => void;
const result = new Promise<T>((_resolve, _reject) => {
Expand All @@ -277,6 +277,7 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
});
this._onExecuteCommand.fire({
reqId,
persistentProcessId,
commandId,
commandArgs: serializedCommandArgs
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack

const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions'];
this._remoteTerminalChannel.onExecuteCommand(async e => {
// Ensure this request for for this window
const pty = this._ptys.get(e.persistentProcessId);
if (!pty) {
return;
}
const reqId = e.reqId;
const commandId = e.commandId;
if (!allowedCommands.includes(commandId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ export class RemoteTerminalChannelClient implements IPtyHostController {
get onProcessOrphanQuestion(): Event<{ id: number }> {
return this._channel.listen<{ id: number }>('$onProcessOrphanQuestion');
}
get onExecuteCommand(): Event<{ reqId: number; commandId: string; commandArgs: any[] }> {
return this._channel.listen<{ reqId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
get onExecuteCommand(): Event<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }> {
return this._channel.listen<{ reqId: number; persistentProcessId: number; commandId: string; commandArgs: any[] }>('$onExecuteCommand');
}
get onDidRequestDetach(): Event<{ requestId: number; workspaceId: string; instanceId: number }> {
return this._channel.listen<{ requestId: number; workspaceId: string; instanceId: number }>('$onDidRequestDetach');
Expand Down

0 comments on commit 677b083

Please sign in to comment.