Browse Source

fix: crash when navigating with render process reuse disabled (#30852)

Robo 3 years ago
parent
commit
1ac4d27e22

+ 12 - 1
shell/browser/api/electron_api_web_contents.cc

@@ -1387,8 +1387,19 @@ void WebContents::HandleNewRenderFrame(
     rwh_impl->disable_hidden_ = !background_throttling_;
 
   auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
-  if (web_frame)
+  if (web_frame) {
+    // When render process reuse is disabled a new siteinstance will always be
+    // forced for every navigation, if a WebFrameMain instance was created
+    // for a FrameTreeNodeId before navigation started, the corresponding
+    // RenderFrameHost will not be the same when the navigation completes.
+    // Compare GlobalFrameRoutingId to avoid incorrect behavior.
+    if (!ElectronBrowserClient::Get()->CanUseCustomSiteInstance() &&
+        web_frame->render_frame_host()->GetGlobalFrameRoutingId() !=
+            render_frame_host->GetGlobalFrameRoutingId()) {
+      return;
+    }
     web_frame->Connect();
+  }
 }
 
 void WebContents::RenderFrameCreated(

+ 12 - 0
spec-main/fixtures/crash-cases/api-web-frame-main-connect/index.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
+    <meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
+    <title>Hello One!</title>
+  </head>
+  <body>
+    <h1>Hello World!</h1>
+  </body>
+</html>

+ 37 - 0
spec-main/fixtures/crash-cases/api-web-frame-main-connect/index.js

@@ -0,0 +1,37 @@
+const { app, BrowserWindow, webContents, protocol } = require('electron');
+const path = require('path');
+
+app.allowRendererProcessReuse = false;
+
+protocol.registerSchemesAsPrivileged([
+  { scheme: 'foo', privileges: { standard: true, secure: true } }
+]);
+
+function createWindow () {
+  const mainWindow = new BrowserWindow({
+    width: 800,
+    height: 600,
+    webPreferences: {
+      nodeIntegration: true,
+      contextIsolation: false
+    }
+  });
+
+  mainWindow.webContents.session.protocol.registerFileProtocol('foo', (request, callback) => {
+    const url = new URL(request.url);
+    callback({ path: `${__dirname}${url.pathname}` });
+  });
+
+  mainWindow.webContents.on('did-finish-load', () => {
+    setImmediate(() => app.quit());
+  });
+
+  // Creates WebFrameMain instance before initiating the navigation.
+  mainWindow.webContents.send('test', 'ping');
+
+  mainWindow.loadURL('foo://app/index.html');
+}
+
+app.whenReady().then(() => {
+  createWindow();
+});