feat: preloads and nodeIntegration in iframes (#16425)

* feat: add support for node / preloads in subframes

This feature has delibrately been built / implemented in such a way
that it has minimum impact on existing apps / code-paths.
Without enabling the new "nodeSupportInSubFrames" option basically none of this
new code will be hit.

The things that I believe need extra scrutiny are:

* Introduction of `event.reply` for IPC events and usage of `event.reply` instead of `event.sender.send()`
* Usage of `node::FreeEnvironment(env)` when the new option is enabled in order to avoid memory leaks.  I have tested this quite a bit and haven't managed to cause a crash but it is still feature flagged behind the "nodeSupportInSubFrames" flag to avoid potential impact.

Closes #10569
Closes #10401
Closes #11868
Closes #12505
Closes #14035

* feat: add support preloads in subframes for sandboxed renderers

* spec: add tests for new nodeSupportInSubFrames option

* spec: fix specs for .reply and ._replyInternal for internal messages

* chore: revert change to use flag instead of environment set size

* chore: clean up subframe impl

* chore: apply suggestions from code review

Co-Authored-By: MarshallOfSound <samuel.r.attard@gmail.com>

* chore: clean up reply usage

* chore: fix TS docs generation

* chore: cleanup after rebase

* chore: rename wrap to add in event fns
This commit is contained in:
Samuel Attard 2019-01-22 11:24:46 -08:00 committed by GitHub
parent 92b9525cfd
commit 58a6fe13d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 332 additions and 49 deletions

View file

@ -139,7 +139,8 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {}
void AtomSandboxedRendererClient::InitializeBindings(
v8::Local<v8::Object> binding,
v8::Local<v8::Context> context) {
v8::Local<v8::Context> context,
bool is_main_frame) {
auto* isolate = context->GetIsolate();
mate::Dictionary b(isolate, binding);
b.SetMethod("get", GetBinding);
@ -154,6 +155,7 @@ void AtomSandboxedRendererClient::InitializeBindings(
process.SetReadOnly("pid", base::GetCurrentProcId());
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();
@ -180,15 +182,23 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
// Only allow preload for the main frame or
// For devtools we still want to run the preload_bundle script
if (!render_frame->IsMainFrame() && !IsDevTools(render_frame) &&
!IsDevToolsExtension(render_frame))
// Or when nodeSupport is explicitly enabled in sub frames
bool is_main_frame = render_frame->IsMainFrame();
bool is_devtools =
IsDevTools(render_frame) || IsDevToolsExtension(render_frame);
bool allow_node_in_sub_frames =
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kNodeIntegrationInSubFrames);
bool should_load_preload =
is_main_frame || is_devtools || allow_node_in_sub_frames;
if (!should_load_preload)
return;
// Wrap the bundle into a function that receives the binding object as
// argument.
auto* isolate = context->GetIsolate();
auto binding = v8::Object::New(isolate);
InitializeBindings(binding, context);
InitializeBindings(binding, context, render_frame->IsMainFrame());
AddRenderBindings(isolate, binding);
std::vector<v8::Local<v8::String>> preload_bundle_params = {
@ -229,7 +239,10 @@ void AtomSandboxedRendererClient::WillReleaseScriptContext(
v8::Handle<v8::Context> context,
content::RenderFrame* render_frame) {
// Only allow preload for the main frame
if (!render_frame->IsMainFrame())
// Or for sub frames when explicitly enabled
if (!render_frame->IsMainFrame() &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kNodeIntegrationInSubFrames))
return;
auto* isolate = context->GetIsolate();