Bug 1646519: Fix GetInProcessTopInternal usage in GetZone. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D80092
This commit is contained in:
Kris Maglione 2020-06-25 21:13:10 +00:00
parent 0fd6caa00d
commit 6f9317a061
3 changed files with 42 additions and 20 deletions

View File

@ -12,6 +12,7 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsGlobalWindowInner.h"
#include "nsRefPtrHashtable.h"
namespace mozilla {
@ -51,6 +52,14 @@ bool WindowContext::IsCached() const {
return mBrowsingContext->mCurrentWindowContext != this;
}
nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
if (mInProcess) {
// FIXME: Replace this with something more efficient.
return nsGlobalWindowInner::GetInnerWindowWithId(mInnerWindowId);
}
return nullptr;
}
WindowContext* WindowContext::GetParentWindowContext() {
return mBrowsingContext->GetParentWindowContext();
}

View File

@ -12,6 +12,8 @@
#include "mozilla/dom/MaybeDiscarded.h"
#include "mozilla/dom/SyncedContext.h"
class nsGlobalWindowInner;
namespace mozilla {
namespace dom {
@ -71,7 +73,9 @@ class WindowContext : public nsISupports, public nsWrapperCache {
bool IsCached() const;
bool IsInProcess() { return mInProcess; }
bool IsInProcess() const { return mInProcess; }
nsGlobalWindowInner* GetInnerWindow() const;
// Get the parent WindowContext of this WindowContext, taking the BFCache into
// account. This will not cross chrome/content <browser> boundaries.

View File

@ -1951,29 +1951,38 @@ static JS::RealmCreationOptions& SelectZone(
return aOptions.setExistingCompartment(xpc::PrivilegedJunkScope());
}
if (aNewInner->GetOuterWindow()) {
nsGlobalWindowOuter* top = aNewInner->GetInProcessTopInternal();
if (top == aNewInner->GetOuterWindow()) {
// We're a toplevel load. Use a new zone. This way, when we do
// zone-based compartment sharing we won't share compartments
// across navigations.
return aOptions.setNewCompartmentAndZone();
}
BrowsingContext* bc = aNewInner->GetBrowsingContext();
if (bc->IsTop()) {
// We're a toplevel load. Use a new zone. This way, when we do
// zone-based compartment sharing we won't share compartments
// across navigations.
return aOptions.setNewCompartmentAndZone();
}
// If we have a top-level window, use its zone.
if (top && top->GetGlobalJSObject()) {
JS::Zone* zone = JS::GetObjectZone(top->GetGlobalJSObject());
// Now try to find an existing compartment that's same-origin
// with our principal.
CompartmentFinderState data(aPrincipal);
JS_IterateCompartmentsInZone(aCx, zone, &data, FindSameOriginCompartment);
if (data.compartment) {
return aOptions.setExistingCompartment(data.compartment);
}
return aOptions.setNewCompartmentInExistingZone(top->GetGlobalJSObject());
// Find the in-process ancestor highest in the hierarchy.
nsGlobalWindowInner* ancestor = nullptr;
for (WindowContext* wc =
aNewInner->GetWindowContext()->GetParentWindowContext();
wc; wc = wc->GetParentWindowContext()) {
if (nsGlobalWindowInner* win = wc->GetInnerWindow()) {
ancestor = win;
}
}
// If we have an ancestor window, use its zone.
if (ancestor && ancestor->GetGlobalJSObject()) {
JS::Zone* zone = JS::GetObjectZone(ancestor->GetGlobalJSObject());
// Now try to find an existing compartment that's same-origin
// with our principal.
CompartmentFinderState data(aPrincipal);
JS_IterateCompartmentsInZone(aCx, zone, &data, FindSameOriginCompartment);
if (data.compartment) {
return aOptions.setExistingCompartment(data.compartment);
}
return aOptions.setNewCompartmentInExistingZone(
ancestor->GetGlobalJSObject());
}
return aOptions.setNewCompartmentAndZone();
}