Skip to content

Commit

Permalink
fix: load window-setup in sandboxed renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
miniak committed Dec 8, 2019
1 parent e3f36d3 commit 4812b31
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 43 deletions.
1 change: 1 addition & 0 deletions filenames.auto.gni
Expand Up @@ -165,6 +165,7 @@ auto_filenames = {
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/renderer/window-setup.ts",
"lib/sandboxed_renderer/api/exports/electron.ts",
"lib/sandboxed_renderer/api/module-list.ts",
"lib/sandboxed_renderer/init.js",
Expand Down
6 changes: 4 additions & 2 deletions lib/browser/guest-window-manager.js
Expand Up @@ -74,8 +74,10 @@ const mergeBrowserWindowOptions = function (embedder, options) {
}
}

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

return options
}
Expand Down
4 changes: 4 additions & 0 deletions lib/browser/rpc-server.js
Expand Up @@ -112,11 +112,15 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event)
contentScripts = getContentScripts()
}

const webPreferences = event.sender.getLastWebPreferences() || {}

return {
contentScripts,
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),
guestInstanceId: webPreferences.guestInstanceId,
openerId: webPreferences.openerId,
process: {
arch: process.arch,
platform: process.platform,
Expand Down
36 changes: 19 additions & 17 deletions lib/renderer/window-setup.ts
Expand Up @@ -197,10 +197,10 @@ export const windowSetup = (
return null
}
}
}

if (openerId != null) {
window.opener = getOrCreateProxy(openerId)
}
if (openerId != null) {
window.opener = getOrCreateProxy(openerId)
}

// But we do not support prompt().
Expand All @@ -227,23 +227,25 @@ export const windowSetup = (
window.dispatchEvent(event as MessageEvent)
})

window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
}

window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
}
if (!process.sandboxed) {
window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
}

window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
}
window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
}

Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
}
})

Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
}
})
}

if (guestInstanceId != null) {
// Webview `document.visibilityState` tracks window visibility (and ignores
Expand Down
18 changes: 15 additions & 3 deletions lib/sandboxed_renderer/init.js
Expand Up @@ -30,7 +30,7 @@ const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-rendere
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')

const {
contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, process: processProps
contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, guestInstanceId, openerId, process: processProps
} = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_SANDBOX_LOAD')

process.isRemoteModuleEnabled = isRemoteModuleEnabled
Expand Down Expand Up @@ -109,6 +109,11 @@ function preloadRequire (module) {
const { hasSwitch } = process.electronBinding('command_line')

const contextIsolation = hasSwitch('context-isolation')
const isHiddenPage = hasSwitch('hidden-page')
const usesNativeWindowOpen = true

// The arguments to be passed to isolated world.
const isolatedWorldArgs = { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen }

switch (window.location.protocol) {
case 'devtools:': {
Expand All @@ -127,21 +132,28 @@ switch (window.location.protocol) {
break
}
default: {
// Override default web functions.
const { windowSetup } = require('@electron/internal/renderer/window-setup')
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)

// Inject content scripts.
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
}
}

const guestInstanceId = binding.guestInstanceId && parseInt(binding.guestInstanceId)

// Load webview tag implementation.
if (process.isMainFrame) {
const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init')
webViewInit(contextIsolation, isWebViewTagEnabled, guestInstanceId)
}

// Pass the arguments to isolatedWorld.
if (contextIsolation) {
v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
}

// Wrap the script into a function executed in global scope. It won't have
// access to the current scope, so we'll expose a few objects as arguments:
//
Expand Down
6 changes: 0 additions & 6 deletions shell/renderer/atom_sandboxed_renderer_client.cc
Expand Up @@ -141,12 +141,6 @@ void AtomSandboxedRendererClient::InitializeBindings(
process.SetReadOnly("sandboxed", true);
process.SetReadOnly("type", "renderer");
process.SetReadOnly("isMainFrame", is_main_frame);

// Pass in CLI flags needed to setup the renderer
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kGuestInstanceID))
b.Set(options::kGuestInstanceID,
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
}

void AtomSandboxedRendererClient::RenderFrameCreated(
Expand Down
35 changes: 20 additions & 15 deletions spec-main/chromium-spec.ts
Expand Up @@ -687,22 +687,27 @@ describe('chromium features', () => {

describe('when opened from main window', () => {
for (const { parent, child, nodeIntegration, nativeWindowOpen, openerAccessible } of table) {
const description = `when parent=${s(parent)} opens child=${s(child)} with nodeIntegration=${nodeIntegration} nativeWindowOpen=${nativeWindowOpen}, child should ${openerAccessible ? '' : 'not '}be able to access opener`
it(description, async () => {
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, nativeWindowOpen } })
await w.loadURL(parent)
const childOpenerLocation = await w.webContents.executeJavaScript(`new Promise(resolve => {
window.addEventListener('message', function f(e) {
resolve(e.data)
for (const sandboxPopup of [false, true]) {
const description = `when parent=${s(parent)} opens child=${s(child)} with nodeIntegration=${nodeIntegration} nativeWindowOpen=${nativeWindowOpen} sandboxPopup=${sandboxPopup}, child should ${openerAccessible ? '' : 'not '}be able to access opener`
it(description, async () => {
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, nativeWindowOpen } })
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
options!.webPreferences!.sandbox = sandboxPopup
})
window.open(${JSON.stringify(child)}, "", "show=no,nodeIntegration=${nodeIntegration ? 'yes' : 'no'}")
})`)
if (openerAccessible) {
expect(childOpenerLocation).to.be.a('string')
} else {
expect(childOpenerLocation).to.be.null()
}
})
await w.loadURL(parent)
const childOpenerLocation = await w.webContents.executeJavaScript(`new Promise(resolve => {
window.addEventListener('message', function f(e) {
resolve(e.data)
})
window.open(${JSON.stringify(child)}, "", "show=no,nodeIntegration=${nodeIntegration ? 'yes' : 'no'}")
})`)
if (openerAccessible) {
expect(childOpenerLocation).to.be.a('string')
} else {
expect(childOpenerLocation).to.be.null()
}
})
}
}
})

Expand Down

0 comments on commit 4812b31

Please sign in to comment.