Browse Source

chore: simplify main world setup of contextIsolation (#16065)

Cheng Zhao 6 years ago
parent
commit
80ef116265

+ 3 - 2
atom/renderer/atom_render_frame_observer.cc

@@ -96,9 +96,10 @@ void AtomRenderFrameObserver::DidCreateScriptContext(
     renderer_client_->DidCreateScriptContext(context, render_frame_);
 
   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();
-    renderer_client_->SetupMainWorldOverrides(context);
+    renderer_client_->SetupMainWorldOverrides(context, render_frame_);
   }
 }
 

+ 10 - 22
atom/renderer/atom_renderer_client.cc

@@ -12,7 +12,6 @@
 #include "atom/common/asar/asar_util.h"
 #include "atom/common/node_bindings.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/web_worker_observer.h"
 #include "base/command_line.h"
@@ -189,13 +188,14 @@ void AtomRendererClient::WillDestroyWorkerContextOnWorkerThread(
 }
 
 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
   v8::Isolate* isolate = context->GetIsolate();
 
-  // 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.
-  std::string left = "(function (binding, require) {\n";
+  std::string left = "(function (nodeProcess, isolatedWorld) {\n";
   std::string right = "\n})";
   auto script = v8::Script::Compile(v8::String::Concat(
       mate::ConvertToV8(isolate, left)->ToString(),
@@ -204,24 +204,12 @@ void AtomRendererClient::SetupMainWorldOverrides(
   auto func =
       v8::Handle<v8::Function>::Cast(script->Run(context).ToLocalChecked());
 
-  auto binding = v8::Object::New(isolate);
-  api::Initialize(binding, v8::Null(isolate), context, nullptr);
-
-  // Pass in CLI flags needed to setup window
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  mate::Dictionary dict(isolate, binding);
-  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(func->Call(context, v8::Null(isolate), 1, args));
+  v8::Local<v8::Value> args[] = {
+      GetEnvironment(render_frame)->process_object(),
+      GetContext(render_frame->GetWebFrame(), isolate)->Global(),
+  };
+  ignore_result(
+      func->Call(context, v8::Null(isolate), node::arraysize(args), args));
 }
 
 node::Environment* AtomRendererClient::GetEnvironment(

+ 2 - 1
atom/renderer/atom_renderer_client.h

@@ -31,7 +31,8 @@ class AtomRendererClient : public RendererClientBase {
                               content::RenderFrame* render_frame) override;
   void WillReleaseScriptContext(v8::Handle<v8::Context> context,
                                 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:
   enum NodeIntegration {

+ 2 - 1
atom/renderer/atom_sandboxed_renderer_client.h

@@ -28,7 +28,8 @@ class AtomSandboxedRendererClient : public RendererClientBase {
                               content::RenderFrame* render_frame) override;
   void WillReleaseScriptContext(v8::Handle<v8::Context> context,
                                 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:
   void RenderFrameCreated(content::RenderFrame*) override;
   void RenderViewCreated(content::RenderView*) override;

+ 2 - 1
atom/renderer/renderer_client_base.h

@@ -32,7 +32,8 @@ class RendererClientBase : public content::ContentRendererClient {
   virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
                                         content::RenderFrame* render_frame) = 0;
   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_; }
 

+ 6 - 20
lib/isolated_renderer/init.js

@@ -1,25 +1,11 @@
 '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 = {
-  send (...args) {
-    return send('ipc-internal-message', args)
-  },
+const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args')
+const { ipcRenderer, guestInstanceId, hiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs
 
-  sendSync (...args) {
-    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)
+require('@electron/internal/renderer/window-setup')(ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNativeWindowOpen)

+ 9 - 0
lib/renderer/override.js

@@ -2,8 +2,17 @@
 
 const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
 
+const v8Util = process.atomBinding('v8_util')
+
 const { guestInstanceId, openerId } = process
 const hiddenPage = process.argv.includes('--hidden-page')
 const usesNativeWindowOpen = process.argv.includes('--native-window-open')
+const contextIsolation = process.argv.includes('--context-isolation')
+
+// Pass the arguments to isolatedWorld.
+if (contextIsolation) {
+  const isolatedWorldArgs = { ipcRenderer, guestInstanceId, hiddenPage, openerId, usesNativeWindowOpen }
+  v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
+}
 
 require('@electron/internal/renderer/window-setup')(ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNativeWindowOpen)