Bug 1576407: Follow-up: Ignore window.opener get/set when BrowsingContext is discarded. r=nika
authorKris Maglione <maglione.k@gmail.com>
Wed, 28 Aug 2019 21:50:44 +0000
changeset 551533 277b0a847f203afc93edd302f7ad1e9a4d14524c
parent 551532 79e99efa822e3f6fc1fa483da4104f9211b62946
child 551534 e43b42cf9c65b318150af31c960faf91c35a816c
push id11865
push userbtara@mozilla.com
push dateMon, 02 Sep 2019 08:54:37 +0000
treeherdermozilla-beta@37f59c4671b3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1576407
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1576407: Follow-up: Ignore window.opener get/set when BrowsingContext is discarded. r=nika MANUAL PUSH: Can't update patch on phabricator. Differential Revision: https://phabricator.services.mozilla.com/D43833
docshell/base/BrowsingContext.h
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowOuter.cpp
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -204,17 +204,23 @@ class BrowsingContext : public nsWrapper
   bool IsTopContent() const { return IsContent() && !GetParent(); }
 
   uint64_t Id() const { return mBrowsingContextId; }
 
   BrowsingContext* GetParent() const { return mParent; }
 
   BrowsingContext* Top();
 
-  already_AddRefed<BrowsingContext> GetOpener() const { return Get(mOpenerId); }
+  already_AddRefed<BrowsingContext> GetOpener() const {
+    RefPtr<BrowsingContext> opener(Get(mOpenerId));
+    if (opener && !opener->mIsDiscarded) {
+      return opener.forget();
+    }
+    return nullptr;
+  }
   void SetOpener(BrowsingContext* aOpener) {
     MOZ_DIAGNOSTIC_ASSERT(!aOpener || aOpener->Group() == Group());
     SetOpenerId(aOpener ? aOpener->Id() : 0);
   }
 
   bool HasOpener() const;
 
   bool HadOriginalOpener() const { return mHadOriginalOpener; }
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -3052,17 +3052,20 @@ void nsGlobalWindowInner::GetOpener(JSCo
     aError.NoteJSContextException(aCx);
   }
 }
 
 void nsGlobalWindowInner::SetOpener(JSContext* aCx,
                                     JS::Handle<JS::Value> aOpener,
                                     ErrorResult& aError) {
   if (aOpener.isNull()) {
-    GetBrowsingContext()->SetOpener(nullptr);
+    RefPtr<BrowsingContext> bc(GetBrowsingContext());
+    if (!bc->IsDiscarded()) {
+      bc->SetOpener(nullptr);
+    }
     return;
   }
 
   // If something other than null is passed, just define aOpener on our inner
   // window's JS object, wrapped into the current compartment so that for Xrays
   // we define on the Xray expando object, but don't set it on the outer window,
   // so that it'll get reset on navigation.  This is just like replaceable
   // properties, but we're not quite readonly.
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -3219,17 +3219,22 @@ nsIControllers* nsGlobalWindowOuter::Get
 }
 
 nsresult nsGlobalWindowOuter::GetControllers(nsIControllers** aResult) {
   FORWARD_TO_INNER(GetControllers, (aResult), NS_ERROR_UNEXPECTED);
 }
 
 already_AddRefed<BrowsingContext>
 nsGlobalWindowOuter::GetOpenerBrowsingContext() {
-  RefPtr<BrowsingContext> opener = GetBrowsingContext()->GetOpener();
+  RefPtr<BrowsingContext> bc(GetBrowsingContext());
+  if (bc->IsDiscarded()) {
+    return nullptr;
+  }
+
+  RefPtr<BrowsingContext> opener = bc->GetOpener();
   MOZ_DIAGNOSTIC_ASSERT(!opener ||
                         opener->Group() == GetBrowsingContext()->Group());
   if (!opener || opener->Group() != GetBrowsingContext()->Group()) {
     return nullptr;
   }
 
   // Catch the case where we're chrome but the opener is not...
   if (nsContentUtils::LegacyIsCallerChromeOrNativeCode() &&