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…
	
	Add table
		Add a link
		
	
		Reference in a new issue