Commit e9d65d29 authored by Samuel Attard's avatar Samuel Attard Committed by Commit Bot

swap global proxies before initializing the windows proxies

Electron's Context Isolation implementation has a side-effect of
initializing the isolated worlds WindowProxy during the initialization
of the main world WindowProxy as a result of creating the isolated
world inside the DidCreateScriptContext hook.  This results in an
assertion failing in Chromium during a frame swap where it expects to
be able to set a new global_proxy in the WindowProxy of the isolated
world BEFORE it is initialized.

To meet this assumption this patch splits SetGlobalProxy into two
calls, SetGlobalProxyWithoutInitializing and InitializeIfNeeded which
has the same resultant effect but means that all of the global_proxy
objects are set BEFORE any WindowProxy's are initialized.

To further clarify, if an embedder creates and initializes new script
context as a result of a call to DidCreateScriptContext the
"global_proxy_.IsEmpty()" CHECK fails as it doesn't expect that context
to have been initialized yet.

Change-Id: I0efa579a4ec2d93369f3e1fc7a922a459a2300cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2503397Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822052}
parent 2f6d9f2b
......@@ -108,14 +108,6 @@ void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
CHECK(global_proxy_.IsEmpty());
global_proxy_.Set(isolate_, global_proxy);
// Initialize the window proxy now, to re-establish the connection between
// the global object and the v8::Context. This is really only needed for a
// RemoteDOMWindow, since it has no scripting environment of its own.
// Without this, existing script references to a swapped in RemoteDOMWindow
// would be broken until that RemoteDOMWindow was vended again through an
// interface like window.frames.
Initialize();
}
// Create a new environment and setup the global object.
......
......@@ -155,6 +155,8 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
CORE_EXPORT v8::Local<v8::Object> GlobalProxyIfNotDetached();
v8::Local<v8::Object> ReleaseGlobalProxy();
// This does not initialize the window proxy, either Initialize or
// InitializeIfNeeded needs to be called after this method.
void SetGlobalProxy(v8::Local<v8::Object>);
// TODO(dcheng): Temporarily exposed to avoid include cycles. Remove the need
......
......@@ -57,6 +57,15 @@ void WindowProxyManager::SetGlobalProxies(
const GlobalProxyVector& global_proxies) {
for (const auto& entry : global_proxies)
WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxy(entry.second);
// Initialize the window proxies now, to re-establish the connection between
// the global object and the v8::Context. This is really only needed for a
// RemoteDOMWindow, since it has no scripting environment of its own.
// Without this, existing script references to a swapped in RemoteDOMWindow
// would be broken until that RemoteDOMWindow was vended again through an
// interface like window.frames.
for (const auto& entry : global_proxies)
WindowProxyMaybeUninitialized(*entry.first)->InitializeIfNeeded();
}
WindowProxyManager::WindowProxyManager(Frame& frame, FrameType frame_type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment