mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 15:35:20 +01:00
debt - improve ipc validation code
This commit is contained in:
@@ -191,6 +191,9 @@ const RULES = [
|
||||
'Event',
|
||||
'Request'
|
||||
],
|
||||
disallowedTypes: [
|
||||
'ipcMain' // not allowed, use validatedIpcMain instead
|
||||
],
|
||||
disallowedDefinitions: [
|
||||
'lib.dom.d.ts' // no DOM
|
||||
]
|
||||
|
||||
@@ -69,7 +69,7 @@ const NATIVE_TYPES = [
|
||||
'ICommonNativeHostService'
|
||||
];
|
||||
|
||||
const RULES = [
|
||||
const RULES: IRule[] = [
|
||||
|
||||
// Tests: skip
|
||||
{
|
||||
@@ -210,6 +210,9 @@ const RULES = [
|
||||
'Event',
|
||||
'Request'
|
||||
],
|
||||
disallowedTypes: [
|
||||
'ipcMain' // not allowed, use validatedIpcMain instead
|
||||
],
|
||||
disallowedDefinitions: [
|
||||
'lib.dom.d.ts' // no DOM
|
||||
]
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { BrowserWindow, ipcMain, IpcMainEvent, Menu, MenuItem } from 'electron';
|
||||
import { BrowserWindow, IpcMainEvent, Menu, MenuItem } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { CONTEXT_MENU_CHANNEL, CONTEXT_MENU_CLOSE_CHANNEL, IPopupOptions, ISerializableContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
|
||||
|
||||
export function registerContextMenuListener(): void {
|
||||
ipcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
|
||||
validatedIpcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
|
||||
const menu = createMenu(event, onClickChannel, items);
|
||||
|
||||
menu.popup({
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ipcMain, WebContents } from 'electron';
|
||||
import { WebContents } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -16,7 +17,7 @@ interface IIPCEvent {
|
||||
}
|
||||
|
||||
function createScopedOnMessageEvent(senderId: number, eventName: string): Event<VSBuffer | null> {
|
||||
const onMessage = Event.fromNodeEventEmitter<IIPCEvent>(ipcMain, eventName, (event, message) => ({ event, message }));
|
||||
const onMessage = Event.fromNodeEventEmitter<IIPCEvent>(validatedIpcMain, eventName, (event, message) => ({ event, message }));
|
||||
const onMessageFromSender = Event.filter(onMessage, ({ event }) => event.sender.id === senderId);
|
||||
|
||||
return Event.map(onMessageFromSender, ({ message }) => message ? VSBuffer.wrap(message) : message);
|
||||
@@ -30,7 +31,7 @@ export class Server extends IPCServer {
|
||||
private static readonly Clients = new Map<number, IDisposable>();
|
||||
|
||||
private static getOnDidClientConnect(): Event<ClientConnectionEvent> {
|
||||
const onHello = Event.fromNodeEventEmitter<WebContents>(ipcMain, 'vscode:hello', ({ sender }) => sender);
|
||||
const onHello = Event.fromNodeEventEmitter<WebContents>(validatedIpcMain, 'vscode:hello', ({ sender }) => sender);
|
||||
|
||||
return Event.map(onHello, webContents => {
|
||||
const id = webContents.id;
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { BrowserWindow, ipcMain, IpcMainEvent, MessagePortMain } from 'electron';
|
||||
import { BrowserWindow, IpcMainEvent, MessagePortMain } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -50,7 +51,7 @@ export async function connect(window: BrowserWindow): Promise<MessagePortMain> {
|
||||
// Wait until the window has returned the `MessagePort`
|
||||
// We need to filter by the `nonce` to ensure we listen
|
||||
// to the right response.
|
||||
const onMessageChannelResult = Event.fromNodeEventEmitter<{ nonce: string; port: MessagePortMain }>(ipcMain, 'vscode:createMessageChannelResult', (e: IpcMainEvent, nonce: string) => ({ nonce, port: e.ports[0] }));
|
||||
const onMessageChannelResult = Event.fromNodeEventEmitter<{ nonce: string; port: MessagePortMain }>(validatedIpcMain, 'vscode:createMessageChannelResult', (e: IpcMainEvent, nonce: string) => ({ nonce, port: e.ports[0] }));
|
||||
const { port } = await Event.toPromise(Event.once(Event.filter(onMessageChannelResult, e => e.nonce === nonce)));
|
||||
|
||||
return port;
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ipcMain as unsafeIpcMain, IpcMainEvent, IpcMainInvokeEvent } from 'electron';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
type ipcMainListener = (event: IpcMainEvent, ...args: any[]) => void;
|
||||
|
||||
class ValidatedIpcMain implements Event.NodeEventEmitter {
|
||||
|
||||
// We need to keep a map of original listener to the wrapped variant in order
|
||||
// to properly implement `removeListener`. We use a `WeakMap` because we do
|
||||
// not want to prevent the `key` of the map to get garbage collected.
|
||||
private readonly mapListenerToWrapper = new WeakMap<ipcMainListener, ipcMainListener>();
|
||||
|
||||
/**
|
||||
* Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
* `listener(event, args...)`.
|
||||
*/
|
||||
on(channel: string, listener: ipcMainListener): this {
|
||||
|
||||
// Remember the wrapped listener so that later we can
|
||||
// properly implement `removeListener`.
|
||||
const wrappedListener = (event: IpcMainEvent, ...args: any[]) => {
|
||||
if (this.validateEvent(channel, event)) {
|
||||
listener(event, ...args);
|
||||
}
|
||||
};
|
||||
|
||||
this.mapListenerToWrapper.set(listener, wrappedListener);
|
||||
|
||||
unsafeIpcMain.on(channel, wrappedListener);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a one time `listener` function for the event. This `listener` is invoked
|
||||
* only the next time a message is sent to `channel`, after which it is removed.
|
||||
*/
|
||||
once(channel: string, listener: ipcMainListener): this {
|
||||
unsafeIpcMain.once(channel, (event: IpcMainEvent, ...args: any[]) => {
|
||||
if (this.validateEvent(channel, event)) {
|
||||
listener(event, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a handler for an `invoke`able IPC. This handler will be called whenever a
|
||||
* renderer calls `ipcRenderer.invoke(channel, ...args)`.
|
||||
*
|
||||
* If `listener` returns a Promise, the eventual result of the promise will be
|
||||
* returned as a reply to the remote caller. Otherwise, the return value of the
|
||||
* listener will be used as the value of the reply.
|
||||
*
|
||||
* The `event` that is passed as the first argument to the handler is the same as
|
||||
* that passed to a regular event listener. It includes information about which
|
||||
* WebContents is the source of the invoke request.
|
||||
*
|
||||
* Errors thrown through `handle` in the main process are not transparent as they
|
||||
* are serialized and only the `message` property from the original error is
|
||||
* provided to the renderer process. Please refer to #24427 for details.
|
||||
*/
|
||||
handle(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<unknown>): this {
|
||||
unsafeIpcMain.handle(channel, (event: IpcMainInvokeEvent, ...args: any[]) => {
|
||||
if (this.validateEvent(channel, event)) {
|
||||
return listener(event, ...args);
|
||||
}
|
||||
|
||||
return Promise.reject(`Invalid channel '${channel}' or sender for ipcMain.handle() usage.`);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any handler for `channel`, if present.
|
||||
*/
|
||||
removeHandler(channel: string): this {
|
||||
unsafeIpcMain.removeHandler(channel);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified `listener` from the listener array for the specified
|
||||
* `channel`.
|
||||
*/
|
||||
removeListener(channel: string, listener: ipcMainListener): this {
|
||||
const wrappedListener = this.mapListenerToWrapper.get(listener);
|
||||
if (wrappedListener) {
|
||||
unsafeIpcMain.removeListener(channel, wrappedListener);
|
||||
this.mapListenerToWrapper.delete(listener);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private validateEvent(channel: string, event: IpcMainEvent | IpcMainInvokeEvent): boolean {
|
||||
if (!channel || !channel.startsWith('vscode:')) {
|
||||
onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because the channel is unknown.`);
|
||||
return false; // unexpected channel
|
||||
}
|
||||
|
||||
const sender = event.senderFrame;
|
||||
if (!sender) {
|
||||
return true; // happens when renderer uses `ipcRenderer.postMessage` (TODO@bpasero revisit with newer Electron version)
|
||||
}
|
||||
|
||||
const url = sender.url;
|
||||
if (!url) {
|
||||
return true; // seems to happen sometimes from the early `invoke` call from preload script
|
||||
}
|
||||
|
||||
let host = 'unknown';
|
||||
try {
|
||||
host = new URL(url).host;
|
||||
} catch (error) {
|
||||
onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because of a malformed URL '${url}'.`);
|
||||
return false; // unexpected URL
|
||||
}
|
||||
|
||||
if (host !== 'vscode-app') {
|
||||
onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because of a bad origin of '${host}'.`);
|
||||
return false; // unexpected sender
|
||||
}
|
||||
|
||||
if (sender.parent !== null) {
|
||||
onUnexpectedError(`Refused to handle ipcMain event for channel '${channel}' because sender of origin '${host}' is not a main frame.`);
|
||||
return false; // unexpected frame
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A drop-in replacement of `ipcMain` that validates the sender of a message
|
||||
* according to https://github.com/electron/electron/blob/main/docs/tutorial/security.md
|
||||
*
|
||||
* @deprecated direct use of Electron IPC is not encouraged. We have utilities in place
|
||||
* to create services on top of IPC, see `ProxyChannel` for more information.
|
||||
*/
|
||||
export const validatedIpcMain = new ValidatedIpcMain();
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, BrowserWindow, contentTracing, dialog, ipcMain, protocol, session, Session, systemPreferences, WebFrameMain } from 'electron';
|
||||
import { app, BrowserWindow, contentTracing, dialog, protocol, session, Session, systemPreferences, WebFrameMain } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { statSync } from 'fs';
|
||||
import { hostname, release } from 'os';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
@@ -380,7 +381,7 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
//#region Bootstrap IPC Handlers
|
||||
|
||||
ipcMain.handle('vscode:fetchShellEnv', event => {
|
||||
validatedIpcMain.handle('vscode:fetchShellEnv', event => {
|
||||
|
||||
// Prefer to use the args and env from the target window
|
||||
// when resolving the shell env. It is possible that
|
||||
@@ -405,7 +406,7 @@ export class CodeApplication extends Disposable {
|
||||
return this.resolveShellEnvironment(args, env, false);
|
||||
});
|
||||
|
||||
ipcMain.handle('vscode:writeNlsFile', (event, path: unknown, data: unknown) => {
|
||||
validatedIpcMain.handle('vscode:writeNlsFile', (event, path: unknown, data: unknown) => {
|
||||
const uri = this.validateNlsPath([path]);
|
||||
if (!uri || typeof data !== 'string') {
|
||||
throw new Error('Invalid operation (vscode:writeNlsFile)');
|
||||
@@ -414,7 +415,7 @@ export class CodeApplication extends Disposable {
|
||||
return this.fileService.writeFile(uri, VSBuffer.fromString(data));
|
||||
});
|
||||
|
||||
ipcMain.handle('vscode:readNlsFile', async (event, ...paths: unknown[]) => {
|
||||
validatedIpcMain.handle('vscode:readNlsFile', async (event, ...paths: unknown[]) => {
|
||||
const uri = this.validateNlsPath(paths);
|
||||
if (!uri) {
|
||||
throw new Error('Invalid operation (vscode:readNlsFile)');
|
||||
@@ -423,10 +424,10 @@ export class CodeApplication extends Disposable {
|
||||
return (await this.fileService.readFile(uri)).value.toString();
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:toggleDevTools', event => event.sender.toggleDevTools());
|
||||
ipcMain.on('vscode:openDevTools', event => event.sender.openDevTools());
|
||||
validatedIpcMain.on('vscode:toggleDevTools', event => event.sender.toggleDevTools());
|
||||
validatedIpcMain.on('vscode:openDevTools', event => event.sender.openDevTools());
|
||||
|
||||
ipcMain.on('vscode:reloadWindow', event => event.sender.reload());
|
||||
validatedIpcMain.on('vscode:reloadWindow', event => event.sender.reload());
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event as IpcEvent, ipcMain } from 'electron';
|
||||
import { Event as IpcEvent } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IDiagnosticInfo, IDiagnosticInfoOptions, IRemoteDiagnosticError, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
@@ -49,7 +50,7 @@ export class DiagnosticsMainService implements IDiagnosticsMainService {
|
||||
|
||||
window.sendWhenReady('vscode:getDiagnosticInfo', CancellationToken.None, { replyChannel, args });
|
||||
|
||||
ipcMain.once(replyChannel, (_: IpcEvent, data: IRemoteDiagnosticInfo) => {
|
||||
validatedIpcMain.once(replyChannel, (_: IpcEvent, data: IRemoteDiagnosticInfo) => {
|
||||
// No data is returned if getting the connection fails.
|
||||
if (!data) {
|
||||
resolve({ hostName: remoteAuthority, errorMessage: `Unable to resolve connection to '${remoteAuthority}'.` });
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { BrowserWindow, BrowserWindowConstructorOptions, Display, ipcMain, IpcMainEvent, screen } from 'electron';
|
||||
import { BrowserWindow, BrowserWindowConstructorOptions, Display, IpcMainEvent, screen } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { arch, release, type } from 'os';
|
||||
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
@@ -65,14 +66,14 @@ export class IssueMainService implements ICommonIssueService {
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
ipcMain.on('vscode:issueSystemInfoRequest', async event => {
|
||||
validatedIpcMain.on('vscode:issueSystemInfoRequest', async event => {
|
||||
const [info, remoteData] = await Promise.all([this.launchMainService.getMainProcessInfo(), this.diagnosticsMainService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })]);
|
||||
const msg = await this.diagnosticsService.getSystemInfo(info, remoteData);
|
||||
|
||||
this.safeSend(event, 'vscode:issueSystemInfoResponse', msg);
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:listProcesses', async event => {
|
||||
validatedIpcMain.on('vscode:listProcesses', async event => {
|
||||
const processes = [];
|
||||
|
||||
try {
|
||||
@@ -102,7 +103,7 @@ export class IssueMainService implements ICommonIssueService {
|
||||
this.safeSend(event, 'vscode:listProcessesResponse', processes);
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:issueReporterClipboard', async event => {
|
||||
validatedIpcMain.on('vscode:issueReporterClipboard', async event => {
|
||||
const messageOptions = {
|
||||
title: this.productService.nameLong,
|
||||
message: localize('issueReporterWriteToClipboard', "There is too much data to send to GitHub directly. The data will be copied to the clipboard, please paste it into the GitHub issue page that is opened."),
|
||||
@@ -122,12 +123,12 @@ export class IssueMainService implements ICommonIssueService {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:issuePerformanceInfoRequest', async event => {
|
||||
validatedIpcMain.on('vscode:issuePerformanceInfoRequest', async event => {
|
||||
const performanceInfo = await this.getPerformanceInfo();
|
||||
this.safeSend(event, 'vscode:issuePerformanceInfoResponse', performanceInfo);
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:issueReporterConfirmClose', async () => {
|
||||
validatedIpcMain.on('vscode:issueReporterConfirmClose', async () => {
|
||||
const messageOptions = {
|
||||
title: this.productService.nameLong,
|
||||
message: localize('confirmCloseIssueReporter', "Your input will not be saved. Are you sure you want to close this window?"),
|
||||
@@ -152,7 +153,7 @@ export class IssueMainService implements ICommonIssueService {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:workbenchCommand', (_: unknown, commandInfo: { id: any; from: any; args: any }) => {
|
||||
validatedIpcMain.on('vscode:workbenchCommand', (_: unknown, commandInfo: { id: any; from: any; args: any }) => {
|
||||
const { id, from, args } = commandInfo;
|
||||
|
||||
let parentWindow: BrowserWindow | null;
|
||||
@@ -172,23 +173,23 @@ export class IssueMainService implements ICommonIssueService {
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:openExternal', (_: unknown, arg: string) => {
|
||||
validatedIpcMain.on('vscode:openExternal', (_: unknown, arg: string) => {
|
||||
this.nativeHostMainService.openExternal(undefined, arg);
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:closeIssueReporter', event => {
|
||||
validatedIpcMain.on('vscode:closeIssueReporter', event => {
|
||||
if (this.issueReporterWindow) {
|
||||
this.issueReporterWindow.close();
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:closeProcessExplorer', event => {
|
||||
validatedIpcMain.on('vscode:closeProcessExplorer', event => {
|
||||
if (this.processExplorerWindow) {
|
||||
this.processExplorerWindow.close();
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('vscode:windowsInfoRequest', async event => {
|
||||
validatedIpcMain.on('vscode:windowsInfoRequest', async event => {
|
||||
const mainProcessInfo = await this.launchMainService.getMainProcessInfo();
|
||||
this.safeSend(event, 'vscode:windowsInfoResponse', mainProcessInfo.windows);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||
import { app, BrowserWindow } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { Barrier, Promises, timeout } from 'vs/base/common/async';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
@@ -511,11 +512,11 @@ export class LifecycleMainService extends Disposable implements ILifecycleMainSe
|
||||
const okChannel = `vscode:ok${oneTimeEventToken}`;
|
||||
const cancelChannel = `vscode:cancel${oneTimeEventToken}`;
|
||||
|
||||
ipcMain.once(okChannel, () => {
|
||||
validatedIpcMain.once(okChannel, () => {
|
||||
resolve(false); // no veto
|
||||
});
|
||||
|
||||
ipcMain.once(cancelChannel, () => {
|
||||
validatedIpcMain.once(cancelChannel, () => {
|
||||
resolve(true); // veto
|
||||
});
|
||||
|
||||
@@ -528,7 +529,7 @@ export class LifecycleMainService extends Disposable implements ILifecycleMainSe
|
||||
const oneTimeEventToken = this.oneTimeListenerTokenGenerator++;
|
||||
const replyChannel = `vscode:reply${oneTimeEventToken}`;
|
||||
|
||||
ipcMain.once(replyChannel, () => resolve());
|
||||
validatedIpcMain.once(replyChannel, () => resolve());
|
||||
|
||||
window.send('vscode:onWillUnload', { replyChannel, reason });
|
||||
});
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ipcMain, session } from 'electron';
|
||||
import { session } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { FileAccess, Schemas } from 'vs/base/common/network';
|
||||
@@ -138,7 +139,7 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ
|
||||
// Install IPC handler
|
||||
const channel = resource.toString();
|
||||
const handler = async (): Promise<T | undefined> => obj;
|
||||
ipcMain.handle(channel, handler);
|
||||
validatedIpcMain.handle(channel, handler);
|
||||
|
||||
this.logService.trace(`IPC Object URL: Registered new channel ${channel}.`);
|
||||
|
||||
@@ -148,7 +149,7 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ
|
||||
dispose: () => {
|
||||
this.logService.trace(`IPC Object URL: Removed channel ${channel}.`);
|
||||
|
||||
ipcMain.removeHandler(channel);
|
||||
validatedIpcMain.removeHandler(channel);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { BrowserWindow, Event as ElectronEvent, ipcMain, IpcMainEvent, MessagePortMain } from 'electron';
|
||||
import { BrowserWindow, Event as ElectronEvent, IpcMainEvent, MessagePortMain } from 'electron';
|
||||
import { validatedIpcMain } from 'vs/base/parts/ipc/electron-main/ipcMain';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
@@ -49,10 +50,10 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
||||
private registerListeners(): void {
|
||||
|
||||
// Shared process connections from workbench windows
|
||||
ipcMain.on('vscode:createSharedProcessMessageChannel', (e, nonce: string) => this.onWindowConnection(e, nonce));
|
||||
validatedIpcMain.on('vscode:createSharedProcessMessageChannel', (e, nonce: string) => this.onWindowConnection(e, nonce));
|
||||
|
||||
// Shared process worker relay
|
||||
ipcMain.on('vscode:relaySharedProcessWorkerMessageChannel', (e, configuration: ISharedProcessWorkerConfiguration) => this.onWorkerConnection(e, configuration));
|
||||
validatedIpcMain.on('vscode:relaySharedProcessWorkerMessageChannel', (e, configuration: ISharedProcessWorkerConfiguration) => this.onWorkerConnection(e, configuration));
|
||||
|
||||
// Lifecycle
|
||||
this._register(this.lifecycleMainService.onWillShutdown(() => this.onWillShutdown()));
|
||||
@@ -173,7 +174,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
||||
if (!this._whenReady) {
|
||||
// Overall signal that the shared process window was loaded and
|
||||
// all services within have been created.
|
||||
this._whenReady = new Promise<void>(resolve => ipcMain.once('vscode:shared-process->electron-main=init-done', () => {
|
||||
this._whenReady = new Promise<void>(resolve => validatedIpcMain.once('vscode:shared-process->electron-main=init-done', () => {
|
||||
this.logService.trace('SharedProcess: Overall ready');
|
||||
|
||||
resolve();
|
||||
@@ -198,7 +199,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
||||
this.registerWindowListeners();
|
||||
|
||||
// Wait for window indicating that IPC connections are accepted
|
||||
await new Promise<void>(resolve => ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => {
|
||||
await new Promise<void>(resolve => validatedIpcMain.once('vscode:shared-process->electron-main=ipc-ready', () => {
|
||||
this.logService.trace('SharedProcess: IPC ready');
|
||||
|
||||
resolve();
|
||||
|
||||
Reference in New Issue
Block a user