Bug 1540839 - Add Cross Origin Opener Policy case for BC preservation; r=nika

If we're doing a process switch due to the cross origin opener policy
being mismatched, we don't want to preserve the browsing context.

Differential Revision: https://phabricator.services.mozilla.com/D26392
This commit is contained in:
Kyle Machulis 2019-04-05 17:18:08 -07:00
Родитель 9f9436d028
Коммит d0cadc6c25
5 изменённых файлов: 32 добавлений и 13 удалений

Просмотреть файл

@ -1606,6 +1606,7 @@ window._gBrowser = {
remoteType,
sameProcessAsFrameLoader,
recordExecution,
replaceBrowsingContext,
} = {}) {
let isRemote = aBrowser.getAttribute("remote") == "true";
@ -1726,7 +1727,7 @@ window._gBrowser = {
// This call actually switches out our frameloaders. Do this as late as
// possible before rebuilding the browser, as we'll need the new browser
// state set up completely first.
aBrowser.changeRemoteness({ remoteType });
aBrowser.changeRemoteness({ remoteType, replaceBrowsingContext });
// Once we have new frameloaders, this call sets the browser back up.
//
// FIXME(emilio): Shouldn't we call destroy() first? What hides the

Просмотреть файл

@ -2296,7 +2296,7 @@ var SessionStoreInternal = {
}
},
async _doTabProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId) {
async _doTabProcessSwitch(aBrowser, aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext) {
debug(`[process-switch]: performing switch from ${aBrowser.remoteType} to ${aRemoteType}`);
// Don't try to switch tabs before delayed startup is completed.
@ -2310,6 +2310,10 @@ var SessionStoreInternal = {
// Information about which channel should be performing the load.
redirectLoadSwitchId: aSwitchId,
// True if this is a process switch due to a policy mismatch, means we
// shouldn't preserve our browsing context.
replaceBrowsingContext: aReplaceBrowsingContext,
};
await SessionStore.navigateAndRestore(tab, loadArguments, -1);
@ -2332,7 +2336,7 @@ var SessionStoreInternal = {
* This method is asynchronous, as it requires multiple calls into content
* processes.
*/
async _doProcessSwitch(aBrowsingContext, aRemoteType, aChannel, aSwitchId) {
async _doProcessSwitch(aBrowsingContext, aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext) {
// There are two relevant cases when performing a process switch for a
// browsing context: in-process and out-of-process embedders.
@ -2341,7 +2345,7 @@ var SessionStoreInternal = {
// traditional mechanism.
if (aBrowsingContext.embedderElement) {
return this._doTabProcessSwitch(aBrowsingContext.embedderElement,
aRemoteType, aChannel, aSwitchId);
aRemoteType, aChannel, aSwitchId, aReplaceBrowsingContext);
}
let wg = aBrowsingContext.embedderWindowGlobal;
@ -2443,13 +2447,17 @@ var SessionStoreInternal = {
return;
}
const isCOOPSwitch = E10SUtils.useCrossOriginOpenerPolicy() &&
aChannel.hasCrossOriginOpenerPolicyMismatch();
// ------------------------------------------------------------------------
// DANGER ZONE: Perform a process switch into the new process. This is
// destructive.
// ------------------------------------------------------------------------
let identifier = ++this._switchIdMonotonic;
let tabPromise = this._doProcessSwitch(browsingContext, remoteType,
aChannel, identifier);
aChannel, identifier,
isCOOPSwitch);
aChannel.switchProcessTo(tabPromise, identifier);
},
@ -3296,6 +3304,7 @@ var SessionStoreInternal = {
// the loadArguments.
newFrameloader: loadArguments.newFrameloader,
remoteType: loadArguments.remoteType,
replaceBrowsingContext: loadArguments.replaceBrowsingContext,
// Make sure that SessionStore knows that this restoration is due
// to a navigation, as opposed to us restoring a closed window or tab.
restoreContentReason: RESTORE_TAB_CONTENT_REASON.NAVIGATE_AND_RESTORE,
@ -4258,18 +4267,21 @@ var SessionStoreInternal = {
this.markTabAsRestoring(aTab);
let newFrameloader = aOptions.newFrameloader;
let replaceBrowsingContext = aOptions.replaceBrowsingContext;
let isRemotenessUpdate;
if (aOptions.remoteType !== undefined) {
// We already have a selected remote type so we update to that.
isRemotenessUpdate =
tabbrowser.updateBrowserRemoteness(browser,
{ remoteType: aOptions.remoteType,
newFrameloader });
newFrameloader,
replaceBrowsingContext,
});
} else {
isRemotenessUpdate =
tabbrowser.updateBrowserRemotenessByURL(browser, uri, {
newFrameloader,
replaceBrowsingContext,
});
}

Просмотреть файл

@ -33,12 +33,17 @@ nsFrameLoaderOwner::GetBrowsingContext() {
void nsFrameLoaderOwner::ChangeRemoteness(
const mozilla::dom::RemotenessOptions& aOptions, mozilla::ErrorResult& rv) {
RefPtr<mozilla::dom::BrowsingContext> bc;
// If we already have a Frameloader, destroy it.
if (mFrameLoader) {
bc = mFrameLoader->GetBrowsingContext();
// TODO pass in Cross-Origin-Load-Policy rules
mFrameLoader->SkipBrowsingContextDetach();
// If we already have a Frameloader, destroy it, possibly preserving its
// browsing context.
if (mFrameLoader) {
// If this is a process switch due to a difference in Cross Origin Opener
// Policy, do not preserve the browsing context. Otherwise, save off the
// browsing context and use it when creating our new FrameLoader.
if (!aOptions.mReplaceBrowsingContext) {
bc = mFrameLoader->GetBrowsingContext();
mFrameLoader->SkipBrowsingContextDetach();
}
mFrameLoader->Destroy();
mFrameLoader = nullptr;

Просмотреть файл

@ -555,7 +555,7 @@ class BrowserChild final : public BrowserChildBase,
mozilla::ipc::IPCResult RecvUpdateNativeWindowHandle(
const uintptr_t& aNewHandle);
virtual mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach() override;
mozilla::ipc::IPCResult RecvSkipBrowsingContextDetach();
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/

Просмотреть файл

@ -13,6 +13,7 @@ dictionary RemotenessOptions {
// it will be used rather than the `src` & `srcdoc` attributes on the
// frameloader to control the load behaviour.
unsigned long long pendingSwitchID;
boolean replaceBrowsingContext = false;
};
[NoInterfaceObject]