chore: simplify main world setup of contextIsolation (#16046)
This commit is contained in:
parent
d6d245d0c3
commit
897c6e93cb
7 changed files with 34 additions and 49 deletions
|
@ -96,9 +96,10 @@ void AtomRenderFrameObserver::DidCreateScriptContext(
|
||||||
renderer_client_->DidCreateScriptContext(context, render_frame_);
|
renderer_client_->DidCreateScriptContext(context, render_frame_);
|
||||||
|
|
||||||
if (renderer_client_->isolated_world() && IsMainWorld(world_id) &&
|
if (renderer_client_->isolated_world() && IsMainWorld(world_id) &&
|
||||||
render_frame_->IsMainFrame()) {
|
// Only the top window's main frame has isolated world.
|
||||||
|
render_frame_->IsMainFrame() && !render_frame_->GetWebFrame()->Opener()) {
|
||||||
CreateIsolatedWorldContext();
|
CreateIsolatedWorldContext();
|
||||||
renderer_client_->SetupMainWorldOverrides(context);
|
renderer_client_->SetupMainWorldOverrides(context, render_frame_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "atom/common/asar/asar_util.h"
|
#include "atom/common/asar/asar_util.h"
|
||||||
#include "atom/common/node_bindings.h"
|
#include "atom/common/node_bindings.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
|
||||||
#include "atom/renderer/atom_render_frame_observer.h"
|
#include "atom/renderer/atom_render_frame_observer.h"
|
||||||
#include "atom/renderer/web_worker_observer.h"
|
#include "atom/renderer/web_worker_observer.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
@ -187,15 +186,16 @@ void AtomRendererClient::WillDestroyWorkerContextOnWorkerThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomRendererClient::SetupMainWorldOverrides(
|
void AtomRendererClient::SetupMainWorldOverrides(
|
||||||
v8::Handle<v8::Context> context) {
|
v8::Handle<v8::Context> context,
|
||||||
|
content::RenderFrame* render_frame) {
|
||||||
// Setup window overrides in the main world context
|
// Setup window overrides in the main world context
|
||||||
v8::Isolate* isolate = context->GetIsolate();
|
v8::Isolate* isolate = context->GetIsolate();
|
||||||
v8::HandleScope handle_scope(isolate);
|
v8::HandleScope handle_scope(isolate);
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
|
|
||||||
// Wrap the bundle into a function that receives the binding object as
|
// Wrap the bundle into a function that receives the isolatedWorld as
|
||||||
// an argument.
|
// an argument.
|
||||||
std::string left = "(function (binding, require) {\n";
|
std::string left = "(function (nodeProcess, isolatedWorld) {\n";
|
||||||
std::string right = "\n})";
|
std::string right = "\n})";
|
||||||
auto source = v8::String::Concat(
|
auto source = v8::String::Concat(
|
||||||
isolate, mate::ConvertToV8(isolate, left)->ToString(isolate),
|
isolate, mate::ConvertToV8(isolate, left)->ToString(isolate),
|
||||||
|
@ -203,28 +203,14 @@ void AtomRendererClient::SetupMainWorldOverrides(
|
||||||
node::isolated_bundle_value.ToStringChecked(isolate),
|
node::isolated_bundle_value.ToStringChecked(isolate),
|
||||||
mate::ConvertToV8(isolate, right)->ToString(isolate)));
|
mate::ConvertToV8(isolate, right)->ToString(isolate)));
|
||||||
auto result = RunScript(context, source);
|
auto result = RunScript(context, source);
|
||||||
|
|
||||||
DCHECK(result->IsFunction());
|
DCHECK(result->IsFunction());
|
||||||
|
|
||||||
auto binding = v8::Object::New(isolate);
|
v8::Local<v8::Value> args[] = {
|
||||||
api::Initialize(binding, v8::Null(isolate), context, nullptr);
|
GetEnvironment(render_frame)->process_object(),
|
||||||
|
GetContext(render_frame->GetWebFrame(), isolate)->Global(),
|
||||||
// Pass in CLI flags needed to setup window
|
};
|
||||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
ignore_result(result.As<v8::Function>()->Call(context, v8::Null(isolate),
|
||||||
mate::Dictionary dict(isolate, binding);
|
node::arraysize(args), args));
|
||||||
if (command_line->HasSwitch(switches::kGuestInstanceID))
|
|
||||||
dict.Set(options::kGuestInstanceID,
|
|
||||||
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
|
|
||||||
if (command_line->HasSwitch(switches::kOpenerID))
|
|
||||||
dict.Set(options::kOpenerID,
|
|
||||||
command_line->GetSwitchValueASCII(switches::kOpenerID));
|
|
||||||
dict.Set("hiddenPage", command_line->HasSwitch(switches::kHiddenPage));
|
|
||||||
dict.Set(options::kNativeWindowOpen,
|
|
||||||
command_line->HasSwitch(switches::kNativeWindowOpen));
|
|
||||||
|
|
||||||
v8::Local<v8::Value> args[] = {binding};
|
|
||||||
ignore_result(
|
|
||||||
result.As<v8::Function>()->Call(context, v8::Null(isolate), 1, args));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node::Environment* AtomRendererClient::GetEnvironment(
|
node::Environment* AtomRendererClient::GetEnvironment(
|
||||||
|
|
|
@ -31,7 +31,8 @@ class AtomRendererClient : public RendererClientBase {
|
||||||
content::RenderFrame* render_frame) override;
|
content::RenderFrame* render_frame) override;
|
||||||
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
||||||
content::RenderFrame* render_frame) override;
|
content::RenderFrame* render_frame) override;
|
||||||
void SetupMainWorldOverrides(v8::Handle<v8::Context> context) override;
|
void SetupMainWorldOverrides(v8::Handle<v8::Context> context,
|
||||||
|
content::RenderFrame* render_frame) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum NodeIntegration {
|
enum NodeIntegration {
|
||||||
|
|
|
@ -28,7 +28,8 @@ class AtomSandboxedRendererClient : public RendererClientBase {
|
||||||
content::RenderFrame* render_frame) override;
|
content::RenderFrame* render_frame) override;
|
||||||
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
||||||
content::RenderFrame* render_frame) override;
|
content::RenderFrame* render_frame) override;
|
||||||
void SetupMainWorldOverrides(v8::Handle<v8::Context> context) override {}
|
void SetupMainWorldOverrides(v8::Handle<v8::Context> context,
|
||||||
|
content::RenderFrame* render_frame) override {}
|
||||||
// content::ContentRendererClient:
|
// content::ContentRendererClient:
|
||||||
void RenderFrameCreated(content::RenderFrame*) override;
|
void RenderFrameCreated(content::RenderFrame*) override;
|
||||||
void RenderViewCreated(content::RenderView*) override;
|
void RenderViewCreated(content::RenderView*) override;
|
||||||
|
|
|
@ -32,7 +32,8 @@ class RendererClientBase : public content::ContentRendererClient {
|
||||||
virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
|
||||||
content::RenderFrame* render_frame) = 0;
|
content::RenderFrame* render_frame) = 0;
|
||||||
virtual void DidClearWindowObject(content::RenderFrame* render_frame);
|
virtual void DidClearWindowObject(content::RenderFrame* render_frame);
|
||||||
virtual void SetupMainWorldOverrides(v8::Handle<v8::Context> context) = 0;
|
virtual void SetupMainWorldOverrides(v8::Handle<v8::Context> context,
|
||||||
|
content::RenderFrame* render_frame) = 0;
|
||||||
|
|
||||||
bool isolated_world() const { return isolated_world_; }
|
bool isolated_world() const { return isolated_world_; }
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
/* global binding */
|
/* global nodeProcess, isolatedWorld */
|
||||||
|
|
||||||
const { send, sendSync } = binding
|
// Note: Don't use "process", as it will be replaced by browserify's one.
|
||||||
|
const v8Util = nodeProcess.atomBinding('v8_util')
|
||||||
|
|
||||||
const ipcRenderer = {
|
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args')
|
||||||
send (...args) {
|
const { ipcRenderer, guestInstanceId, hiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs
|
||||||
return send('ipc-internal-message', args)
|
|
||||||
},
|
|
||||||
|
|
||||||
sendSync (...args) {
|
require('@electron/internal/renderer/window-setup')(ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNativeWindowOpen)
|
||||||
return sendSync('ipc-internal-message-sync', args)[0]
|
|
||||||
},
|
|
||||||
|
|
||||||
// No-ops since events aren't received
|
|
||||||
on () {},
|
|
||||||
once () {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let { guestInstanceId, hiddenPage, openerId, nativeWindowOpen } = binding
|
|
||||||
if (guestInstanceId != null) guestInstanceId = parseInt(guestInstanceId)
|
|
||||||
if (openerId != null) openerId = parseInt(openerId)
|
|
||||||
|
|
||||||
require('@electron/internal/renderer/window-setup')(ipcRenderer, guestInstanceId, openerId, hiddenPage, nativeWindowOpen)
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ require('@electron/internal/renderer/web-frame-init')()
|
||||||
// Process command line arguments.
|
// Process command line arguments.
|
||||||
let nodeIntegration = false
|
let nodeIntegration = false
|
||||||
let webviewTag = false
|
let webviewTag = false
|
||||||
|
let contextIsolation = false
|
||||||
let preloadScript = null
|
let preloadScript = null
|
||||||
let preloadScripts = []
|
let preloadScripts = []
|
||||||
let isBackgroundPage = false
|
let isBackgroundPage = false
|
||||||
|
@ -56,6 +57,8 @@ for (const arg of process.argv) {
|
||||||
appPath = arg.substr(arg.indexOf('=') + 1)
|
appPath = arg.substr(arg.indexOf('=') + 1)
|
||||||
} else if (arg.indexOf('--webview-tag=') === 0) {
|
} else if (arg.indexOf('--webview-tag=') === 0) {
|
||||||
webviewTag = arg.substr(arg.indexOf('=') + 1) === 'true'
|
webviewTag = arg.substr(arg.indexOf('=') + 1) === 'true'
|
||||||
|
} else if (arg === '--context-isolation') {
|
||||||
|
contextIsolation = true
|
||||||
} else if (arg.indexOf('--preload-scripts') === 0) {
|
} else if (arg.indexOf('--preload-scripts') === 0) {
|
||||||
preloadScripts = arg.substr(arg.indexOf('=') + 1).split(path.delimiter)
|
preloadScripts = arg.substr(arg.indexOf('=') + 1).split(path.delimiter)
|
||||||
}
|
}
|
||||||
|
@ -69,6 +72,12 @@ if (preloadScript) {
|
||||||
preloadScripts.push(preloadScript)
|
preloadScripts.push(preloadScript)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass the arguments to isolatedWorld.
|
||||||
|
if (contextIsolation) {
|
||||||
|
const isolatedWorldArgs = { ipcRenderer, guestInstanceId, hiddenPage, openerId, usesNativeWindowOpen }
|
||||||
|
v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
|
||||||
|
}
|
||||||
|
|
||||||
if (window.location.protocol === 'chrome-devtools:') {
|
if (window.location.protocol === 'chrome-devtools:') {
|
||||||
// Override some inspector APIs.
|
// Override some inspector APIs.
|
||||||
require('@electron/internal/renderer/inspector')
|
require('@electron/internal/renderer/inspector')
|
||||||
|
|
Loading…
Reference in a new issue