Skip to content

Commit cbf499b

Browse files
miniakzcbenz
authored andcommitted
fix: load window-setup in sandboxed renderer (electron#21696)
1 parent 7b1117e commit cbf499b

File tree

6 files changed

+68
-46
lines changed

6 files changed

+68
-46
lines changed

filenames.auto.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ auto_filenames = {
166166
"lib/renderer/web-view/web-view-element.ts",
167167
"lib/renderer/web-view/web-view-impl.ts",
168168
"lib/renderer/web-view/web-view-init.ts",
169+
"lib/renderer/window-setup.ts",
169170
"lib/sandboxed_renderer/api/exports/electron.js",
170171
"lib/sandboxed_renderer/api/module-list.js",
171172
"lib/sandboxed_renderer/init.js",

lib/browser/guest-window-manager.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ const mergeBrowserWindowOptions = function (embedder, options) {
7575
}
7676
}
7777

78-
// Sets correct openerId here to give correct options to 'new-window' event handler
79-
options.webPreferences.openerId = embedder.id
78+
if (!webPreferences.nativeWindowOpen) {
79+
// Sets correct openerId here to give correct options to 'new-window' event handler
80+
options.webPreferences.openerId = embedder.id
81+
}
8082

8183
return options
8284
}

lib/browser/rpc-server.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,15 @@ ipcMainUtils.handle('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
529529

530530
ipcMainUtils.handle('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
531531
const preloadPaths = event.sender._getPreloadPaths()
532+
const webPreferences = event.sender.getLastWebPreferences() || {}
532533

533534
return {
534535
contentScripts: getContentScripts(),
535536
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
536537
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
537538
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),
539+
guestInstanceId: webPreferences.guestInstanceId,
540+
openerId: webPreferences.openerId,
538541
process: {
539542
arch: process.arch,
540543
platform: process.platform,

lib/renderer/window-setup.ts

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class BrowserWindowProxy {
177177
export const windowSetup = (
178178
guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean
179179
) => {
180-
if (guestInstanceId == null) {
180+
if (!process.sandboxed && guestInstanceId == null) {
181181
// Override default window.close.
182182
window.close = function () {
183183
ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE')
@@ -197,53 +197,57 @@ export const windowSetup = (
197197
return null
198198
}
199199
}
200+
}
200201

201-
if (openerId != null) {
202-
window.opener = getOrCreateProxy(openerId)
203-
}
202+
if (openerId != null) {
203+
window.opener = getOrCreateProxy(openerId)
204204
}
205205

206206
// But we do not support prompt().
207207
window.prompt = function () {
208208
throw new Error('prompt() is and will not be supported.')
209209
}
210210

211-
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
212-
_event, sourceId: number, message: any, sourceOrigin: string
213-
) {
214-
// Manually dispatch event instead of using postMessage because we also need to
215-
// set event.source.
216-
//
217-
// Why any? We can't construct a MessageEvent and we can't
218-
// use `as MessageEvent` because you're not supposed to override
219-
// data, origin, and source
220-
const event: any = document.createEvent('Event')
221-
event.initEvent('message', false, false)
222-
223-
event.data = message
224-
event.origin = sourceOrigin
225-
event.source = getOrCreateProxy(sourceId)
226-
227-
window.dispatchEvent(event as MessageEvent)
228-
})
229-
230-
window.history.back = function () {
231-
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
211+
if (!usesNativeWindowOpen || openerId != null) {
212+
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
213+
_event, sourceId: number, message: any, sourceOrigin: string
214+
) {
215+
// Manually dispatch event instead of using postMessage because we also need to
216+
// set event.source.
217+
//
218+
// Why any? We can't construct a MessageEvent and we can't
219+
// use `as MessageEvent` because you're not supposed to override
220+
// data, origin, and source
221+
const event: any = document.createEvent('Event')
222+
event.initEvent('message', false, false)
223+
224+
event.data = message
225+
event.origin = sourceOrigin
226+
event.source = getOrCreateProxy(sourceId)
227+
228+
window.dispatchEvent(event as MessageEvent)
229+
})
232230
}
233231

234-
window.history.forward = function () {
235-
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
236-
}
232+
if (!process.sandboxed) {
233+
window.history.back = function () {
234+
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
235+
}
237236

238-
window.history.go = function (offset: number) {
239-
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
240-
}
237+
window.history.forward = function () {
238+
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
239+
}
241240

242-
Object.defineProperty(window.history, 'length', {
243-
get: function () {
244-
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
241+
window.history.go = function (offset: number) {
242+
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
245243
}
246-
})
244+
245+
Object.defineProperty(window.history, 'length', {
246+
get: function () {
247+
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
248+
}
249+
})
250+
}
247251

248252
if (guestInstanceId != null) {
249253
// Webview `document.visibilityState` tracks window visibility (and ignores

lib/sandboxed_renderer/init.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-rendere
3030
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
3131

3232
const {
33-
contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, process: processProps
33+
contentScripts,
34+
preloadScripts,
35+
isRemoteModuleEnabled,
36+
isWebViewTagEnabled,
37+
guestInstanceId,
38+
openerId,
39+
process: processProps
3440
} = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_SANDBOX_LOAD')
3541

3642
process.isRemoteModuleEnabled = isRemoteModuleEnabled
@@ -109,6 +115,11 @@ function preloadRequire (module) {
109115
const { hasSwitch } = process.electronBinding('command_line')
110116

111117
const contextIsolation = hasSwitch('context-isolation')
118+
const isHiddenPage = hasSwitch('hidden-page')
119+
const usesNativeWindowOpen = true
120+
121+
// The arguments to be passed to isolated world.
122+
const isolatedWorldArgs = { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen }
112123

113124
switch (window.location.protocol) {
114125
case 'devtools:': {
@@ -125,19 +136,26 @@ switch (window.location.protocol) {
125136
break
126137
}
127138
default: {
139+
// Override default web functions.
140+
const { windowSetup } = require('@electron/internal/renderer/window-setup')
141+
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
142+
128143
// Inject content scripts.
129144
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
130145
}
131146
}
132147

133-
const guestInstanceId = binding.guestInstanceId && parseInt(binding.guestInstanceId)
134-
135148
// Load webview tag implementation.
136149
if (process.isMainFrame) {
137150
const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init')
138151
webViewInit(contextIsolation, isWebViewTagEnabled, guestInstanceId)
139152
}
140153

154+
// Pass the arguments to isolatedWorld.
155+
if (contextIsolation) {
156+
v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
157+
}
158+
141159
const errorUtils = require('@electron/internal/common/error-utils')
142160

143161
// Wrap the script into a function executed in global scope. It won't have

shell/renderer/atom_sandboxed_renderer_client.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,6 @@ void AtomSandboxedRendererClient::InitializeBindings(
144144
process.SetReadOnly("sandboxed", true);
145145
process.SetReadOnly("type", "renderer");
146146
process.SetReadOnly("isMainFrame", is_main_frame);
147-
148-
// Pass in CLI flags needed to setup the renderer
149-
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
150-
if (command_line->HasSwitch(switches::kGuestInstanceID))
151-
b.Set(options::kGuestInstanceID,
152-
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
153147
}
154148

155149
void AtomSandboxedRendererClient::RenderFrameCreated(

0 commit comments

Comments
 (0)