Browse Source

fix: potential exception when calling webFrameMainBinding.fromIdOrNull() (#35785)

* fix: potential exception when calling webFrameMainBinding.fromIdOrNull()

* replace try/catch in getWebFrameForEvent

Co-authored-by: Milan Burda <[email protected]>
Milan Burda 2 years ago
parent
commit
f62aab76b3
2 changed files with 11 additions and 6 deletions
  1. 10 5
      lib/browser/api/web-contents.ts
  2. 1 1
      typings/internal-ambient.d.ts

+ 10 - 5
lib/browser/api/web-contents.ts

@@ -537,6 +537,11 @@ const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
   });
 };
 
+const getWebFrameForEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent) => {
+  if (!event.processId || !event.frameId) return null;
+  return webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
+};
+
 const commandLine = process._linkedBinding('electron_common_command_line');
 const environment = process._linkedBinding('electron_common_environment');
 
@@ -574,7 +579,7 @@ WebContents.prototype._init = function () {
     } else {
       addReplyToEvent(event);
       this.emit('ipc-message', event, channel, ...args);
-      const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
+      const maybeWebFrame = getWebFrameForEvent(event);
       maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, ...args);
       ipc.emit(channel, event, ...args);
       ipcMain.emit(channel, event, ...args);
@@ -588,8 +593,8 @@ WebContents.prototype._init = function () {
       console.error(`Error occurred in handler for '${channel}':`, error);
       event.sendReply({ error: error.toString() });
     };
-    const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
-    const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame && maybeWebFrame.ipc, ipc, ipcMain];
+    const maybeWebFrame = getWebFrameForEvent(event);
+    const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame?.ipc, ipc, ipcMain];
     const target = targets.find(target => target && (target as any)._invokeHandlers.has(channel));
     if (target) {
       (target as any)._invokeHandlers.get(channel)(event, ...args);
@@ -605,7 +610,7 @@ WebContents.prototype._init = function () {
       ipcMainInternal.emit(channel, event, ...args);
     } else {
       addReplyToEvent(event);
-      const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
+      const maybeWebFrame = getWebFrameForEvent(event);
       if (this.listenerCount('ipc-message-sync') === 0 && ipc.listenerCount(channel) === 0 && ipcMain.listenerCount(channel) === 0 && (!maybeWebFrame || maybeWebFrame.ipc.listenerCount(channel) === 0)) {
         console.warn(`WebContents #${this.id} called ipcRenderer.sendSync() with '${channel}' channel without listeners.`);
       }
@@ -619,7 +624,7 @@ WebContents.prototype._init = function () {
   this.on('-ipc-ports' as any, function (event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
     addSenderFrameToEvent(event);
     event.ports = ports.map(p => new MessagePortMain(p));
-    const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
+    const maybeWebFrame = getWebFrameForEvent(event);
     maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, message);
     ipc.emit(channel, event, message);
     ipcMain.emit(channel, event, message);

+ 1 - 1
typings/internal-ambient.d.ts

@@ -237,7 +237,7 @@ declare namespace NodeJS {
     _linkedBinding(name: 'electron_browser_web_frame_main'): {
       WebFrameMain: typeof Electron.WebFrameMain;
       fromId(processId: number, routingId: number): Electron.WebFrameMain;
-      fromIdOrNull(processId: number, routingId: number): Electron.WebFrameMain;
+      fromIdOrNull(processId: number, routingId: number): Electron.WebFrameMain | null;
     }
     _linkedBinding(name: 'electron_renderer_crash_reporter'): Electron.CrashReporter;
     _linkedBinding(name: 'electron_renderer_ipc'): { ipc: IpcRendererBinding };