Commit d0cadc6c authored by Kyle Machulis's avatar Kyle Machulis
Browse files

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
parent 9f9436d0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+18 −6
Original line number Diff line number Diff line
@@ -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,
        });
    }

+10 −5
Original line number Diff line number Diff line
@@ -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 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();

    // TODO pass in Cross-Origin-Load-Policy rules
      mFrameLoader->SkipBrowsingContextDetach();
    }

    mFrameLoader->Destroy();
    mFrameLoader = nullptr;
+1 −1
Original line number Diff line number Diff line
@@ -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.
   */
+1 −0
Original line number Diff line number Diff line
@@ -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]