mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Backed out 2 changesets (bug 1810619) for causing wd failures in dom_content_loaded.py CLOSED TREE
Backed out changeset 81d6ef111d4f (bug 1810619) Backed out changeset 637be53c4d27 (bug 1810619)
This commit is contained in:
parent
32646098cd
commit
2af0d81d29
@ -1194,15 +1194,104 @@ void BrowsingContext::GetAllBrowsingContextsInSubtree(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindWithName follows the rules for choosing a browsing context,
|
||||||
|
// with the exception of sandboxing for iframes. The implementation
|
||||||
|
// for arbitrarily choosing between two browsing contexts with the
|
||||||
|
// same name is as follows:
|
||||||
|
//
|
||||||
|
// 1) The start browsing context, i.e. 'this'
|
||||||
|
// 2) Descendants in insertion order
|
||||||
|
// 3) The parent
|
||||||
|
// 4) Siblings and their children, both in insertion order
|
||||||
|
// 5) After this we iteratively follow the parent chain, repeating 3
|
||||||
|
// and 4 until
|
||||||
|
// 6) If there is no parent, consider all other top level browsing
|
||||||
|
// contexts and their children, both in insertion order
|
||||||
|
//
|
||||||
|
// See
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
|
||||||
|
BrowsingContext* BrowsingContext::FindWithName(
|
||||||
|
const nsAString& aName, bool aUseEntryGlobalForAccessCheck) {
|
||||||
|
RefPtr<BrowsingContext> requestingContext = this;
|
||||||
|
if (aUseEntryGlobalForAccessCheck) {
|
||||||
|
if (nsGlobalWindowInner* caller = nsContentUtils::EntryInnerWindow()) {
|
||||||
|
if (caller->GetBrowsingContextGroup() == Group()) {
|
||||||
|
requestingContext = caller->GetBrowsingContext();
|
||||||
|
} else {
|
||||||
|
MOZ_RELEASE_ASSERT(caller->GetPrincipal()->IsSystemPrincipal(),
|
||||||
|
"caller must be either same-group or system");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(requestingContext, "must have a requestingContext");
|
||||||
|
|
||||||
|
BrowsingContext* found = nullptr;
|
||||||
|
if (aName.IsEmpty()) {
|
||||||
|
// You can't find a browsing context with an empty name.
|
||||||
|
found = nullptr;
|
||||||
|
} else if (aName.LowerCaseEqualsLiteral("_blank")) {
|
||||||
|
// Just return null. Caller must handle creating a new window with
|
||||||
|
// a blank name.
|
||||||
|
found = nullptr;
|
||||||
|
} else if (nsContentUtils::IsSpecialName(aName)) {
|
||||||
|
found = FindWithSpecialName(aName, *requestingContext);
|
||||||
|
} else if (BrowsingContext* child =
|
||||||
|
FindWithNameInSubtree(aName, *requestingContext)) {
|
||||||
|
found = child;
|
||||||
|
} else {
|
||||||
|
BrowsingContext* current = this;
|
||||||
|
|
||||||
|
do {
|
||||||
|
Span<RefPtr<BrowsingContext>> siblings;
|
||||||
|
BrowsingContext* parent = current->GetParent();
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
// We've reached the root of the tree, consider browsing
|
||||||
|
// contexts in the same browsing context group.
|
||||||
|
siblings = mGroup->Toplevels();
|
||||||
|
} else if (parent->NameEquals(aName) &&
|
||||||
|
requestingContext->CanAccess(parent) &&
|
||||||
|
parent->IsTargetable()) {
|
||||||
|
found = parent;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
siblings = parent->NonSyntheticChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BrowsingContext* sibling : siblings) {
|
||||||
|
if (sibling == current) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BrowsingContext* relative =
|
||||||
|
sibling->FindWithNameInSubtree(aName, *requestingContext)) {
|
||||||
|
found = relative;
|
||||||
|
// Breaks the outer loop
|
||||||
|
parent = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current = parent;
|
||||||
|
} while (current);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers should perform access control checks, which means that we
|
||||||
|
// only need to assert that we can access found.
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!found || requestingContext->CanAccess(found));
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
BrowsingContext* BrowsingContext::FindChildWithName(
|
BrowsingContext* BrowsingContext::FindChildWithName(
|
||||||
const nsAString& aName, WindowGlobalChild& aRequestingWindow) {
|
const nsAString& aName, BrowsingContext& aRequestingContext) {
|
||||||
if (aName.IsEmpty()) {
|
if (aName.IsEmpty()) {
|
||||||
// You can't find a browsing context with the empty name.
|
// You can't find a browsing context with the empty name.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BrowsingContext* child : NonSyntheticChildren()) {
|
for (BrowsingContext* child : NonSyntheticChildren()) {
|
||||||
if (child->NameEquals(aName) && aRequestingWindow.CanNavigate(child) &&
|
if (child->NameEquals(aName) && aRequestingContext.CanAccess(child) &&
|
||||||
child->IsTargetable()) {
|
child->IsTargetable()) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@ -1212,7 +1301,7 @@ BrowsingContext* BrowsingContext::FindChildWithName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
BrowsingContext* BrowsingContext::FindWithSpecialName(
|
BrowsingContext* BrowsingContext::FindWithSpecialName(
|
||||||
const nsAString& aName, WindowGlobalChild& aRequestingWindow) {
|
const nsAString& aName, BrowsingContext& aRequestingContext) {
|
||||||
// TODO(farre): Neither BrowsingContext nor nsDocShell checks if the
|
// TODO(farre): Neither BrowsingContext nor nsDocShell checks if the
|
||||||
// browsing context pointed to by a special name is active. Should
|
// browsing context pointed to by a special name is active. Should
|
||||||
// it be? See Bug 1527913.
|
// it be? See Bug 1527913.
|
||||||
@ -1222,7 +1311,7 @@ BrowsingContext* BrowsingContext::FindWithSpecialName(
|
|||||||
|
|
||||||
if (aName.LowerCaseEqualsLiteral("_parent")) {
|
if (aName.LowerCaseEqualsLiteral("_parent")) {
|
||||||
if (BrowsingContext* parent = GetParent()) {
|
if (BrowsingContext* parent = GetParent()) {
|
||||||
return aRequestingWindow.CanNavigate(parent) ? parent : nullptr;
|
return aRequestingContext.CanAccess(parent) ? parent : nullptr;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -1230,25 +1319,24 @@ BrowsingContext* BrowsingContext::FindWithSpecialName(
|
|||||||
if (aName.LowerCaseEqualsLiteral("_top")) {
|
if (aName.LowerCaseEqualsLiteral("_top")) {
|
||||||
BrowsingContext* top = Top();
|
BrowsingContext* top = Top();
|
||||||
|
|
||||||
return aRequestingWindow.CanNavigate(top) ? top : nullptr;
|
return aRequestingContext.CanAccess(top) ? top : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowsingContext* BrowsingContext::FindWithNameInSubtree(
|
BrowsingContext* BrowsingContext::FindWithNameInSubtree(
|
||||||
const nsAString& aName, WindowGlobalChild* aRequestingWindow) {
|
const nsAString& aName, BrowsingContext& aRequestingContext) {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!aName.IsEmpty());
|
MOZ_DIAGNOSTIC_ASSERT(!aName.IsEmpty());
|
||||||
|
|
||||||
if (NameEquals(aName) &&
|
if (NameEquals(aName) && aRequestingContext.CanAccess(this) &&
|
||||||
(!aRequestingWindow || aRequestingWindow->CanNavigate(this)) &&
|
|
||||||
IsTargetable()) {
|
IsTargetable()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BrowsingContext* child : NonSyntheticChildren()) {
|
for (BrowsingContext* child : NonSyntheticChildren()) {
|
||||||
if (BrowsingContext* found =
|
if (BrowsingContext* found =
|
||||||
child->FindWithNameInSubtree(aName, aRequestingWindow)) {
|
child->FindWithNameInSubtree(aName, aRequestingContext)) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1256,6 +1344,48 @@ BrowsingContext* BrowsingContext::FindWithNameInSubtree(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For historical context, see:
|
||||||
|
//
|
||||||
|
// Bug 13871: Prevent frameset spoofing
|
||||||
|
// Bug 103638: Targets with same name in different windows open in wrong
|
||||||
|
// window with javascript
|
||||||
|
// Bug 408052: Adopt "ancestor" frame navigation policy
|
||||||
|
// Bug 1570207: Refactor logic to rely on BrowsingContextGroups to enforce
|
||||||
|
// origin attribute isolation.
|
||||||
|
bool BrowsingContext::CanAccess(BrowsingContext* aTarget,
|
||||||
|
bool aConsiderOpener) {
|
||||||
|
MOZ_ASSERT(
|
||||||
|
mDocShell,
|
||||||
|
"CanAccess() may only be called in the process of the accessing window");
|
||||||
|
MOZ_ASSERT(aTarget, "Must have a target");
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(
|
||||||
|
Group() == aTarget->Group(),
|
||||||
|
"A BrowsingContext should never see a context from a different group");
|
||||||
|
|
||||||
|
// A frame can navigate itself and its own root.
|
||||||
|
if (aTarget == this || aTarget == Top()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A frame can navigate any frame with a same-origin ancestor.
|
||||||
|
for (BrowsingContext* bc = aTarget; bc; bc = bc->GetParent()) {
|
||||||
|
if (bc->mDocShell && nsDocShell::ValidateOrigin(this, bc)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the target is a top-level document, a frame can navigate it if it can
|
||||||
|
// navigate its opener.
|
||||||
|
if (aConsiderOpener && !aTarget->GetParent()) {
|
||||||
|
if (RefPtr<BrowsingContext> opener = aTarget->GetOpener()) {
|
||||||
|
return CanAccess(opener, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool BrowsingContext::IsSandboxedFrom(BrowsingContext* aTarget) {
|
bool BrowsingContext::IsSandboxedFrom(BrowsingContext* aTarget) {
|
||||||
// If no target then not sandboxed.
|
// If no target then not sandboxed.
|
||||||
if (!aTarget) {
|
if (!aTarget) {
|
||||||
@ -1940,12 +2070,13 @@ nsresult BrowsingContext::LoadURI(nsDocShellLoadState* aLoadState,
|
|||||||
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!sourceBC || sourceBC->Group() == Group());
|
MOZ_DIAGNOSTIC_ASSERT(!sourceBC || sourceBC->Group() == Group());
|
||||||
if (sourceBC && sourceBC->IsInProcess()) {
|
if (sourceBC && sourceBC->IsInProcess()) {
|
||||||
|
if (!sourceBC->CanAccess(this)) {
|
||||||
|
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> win(sourceBC->GetDOMWindow());
|
nsCOMPtr<nsPIDOMWindowOuter> win(sourceBC->GetDOMWindow());
|
||||||
if (WindowGlobalChild* wgc =
|
if (WindowGlobalChild* wgc =
|
||||||
win->GetCurrentInnerWindow()->GetWindowGlobalChild()) {
|
win->GetCurrentInnerWindow()->GetWindowGlobalChild()) {
|
||||||
if (!wgc->CanNavigate(this)) {
|
|
||||||
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
wgc->SendLoadURI(this, aLoadState, aSetNavigating);
|
wgc->SendLoadURI(this, aLoadState, aSetNavigating);
|
||||||
}
|
}
|
||||||
} else if (XRE_IsParentProcess()) {
|
} else if (XRE_IsParentProcess()) {
|
||||||
@ -2044,15 +2175,16 @@ nsresult BrowsingContext::InternalLoad(nsDocShellLoadState* aLoadState) {
|
|||||||
MOZ_DIAGNOSTIC_ASSERT(sourceBC);
|
MOZ_DIAGNOSTIC_ASSERT(sourceBC);
|
||||||
MOZ_DIAGNOSTIC_ASSERT(sourceBC->Group() == Group());
|
MOZ_DIAGNOSTIC_ASSERT(sourceBC->Group() == Group());
|
||||||
|
|
||||||
|
if (!sourceBC->CanAccess(this)) {
|
||||||
|
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> win(sourceBC->GetDOMWindow());
|
nsCOMPtr<nsPIDOMWindowOuter> win(sourceBC->GetDOMWindow());
|
||||||
WindowGlobalChild* wgc =
|
WindowGlobalChild* wgc =
|
||||||
win->GetCurrentInnerWindow()->GetWindowGlobalChild();
|
win->GetCurrentInnerWindow()->GetWindowGlobalChild();
|
||||||
if (!wgc || !wgc->CanSend()) {
|
if (!wgc || !wgc->CanSend()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
if (!wgc->CanNavigate(this)) {
|
|
||||||
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ALWAYS_SUCCEEDS(
|
MOZ_ALWAYS_SUCCEEDS(
|
||||||
SetCurrentLoadIdentifier(Some(aLoadState->GetLoadIdentifier())));
|
SetCurrentLoadIdentifier(Some(aLoadState->GetLoadIdentifier())));
|
||||||
|
@ -75,7 +75,6 @@ class SessionHistoryInfo;
|
|||||||
class SessionStorageManager;
|
class SessionStorageManager;
|
||||||
class StructuredCloneHolder;
|
class StructuredCloneHolder;
|
||||||
class WindowContext;
|
class WindowContext;
|
||||||
class WindowGlobalChild;
|
|
||||||
struct WindowPostMessageOptions;
|
struct WindowPostMessageOptions;
|
||||||
class WindowProxyHolder;
|
class WindowProxyHolder;
|
||||||
|
|
||||||
@ -660,26 +659,32 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Using the rules for choosing a browsing context we try to find
|
||||||
|
// the browsing context with the given name in the set of
|
||||||
|
// transitively reachable browsing contexts. Performs access control
|
||||||
|
// checks with regard to this.
|
||||||
|
// See
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name.
|
||||||
|
//
|
||||||
|
// BrowsingContext::FindWithName(const nsAString&) is equivalent to
|
||||||
|
// calling nsIDocShellTreeItem::FindItemWithName(aName, nullptr,
|
||||||
|
// nullptr, false, <return value>).
|
||||||
|
BrowsingContext* FindWithName(const nsAString& aName,
|
||||||
|
bool aUseEntryGlobalForAccessCheck = true);
|
||||||
|
|
||||||
// Find a browsing context in this context's list of
|
// Find a browsing context in this context's list of
|
||||||
// children. Doesn't consider the special names, '_self', '_parent',
|
// children. Doesn't consider the special names, '_self', '_parent',
|
||||||
// '_top', or '_blank'. Performs access control checks with regard to
|
// '_top', or '_blank'. Performs access control checks with regard to
|
||||||
// 'this'.
|
// 'this'.
|
||||||
BrowsingContext* FindChildWithName(const nsAString& aName,
|
BrowsingContext* FindChildWithName(const nsAString& aName,
|
||||||
WindowGlobalChild& aRequestingWindow);
|
BrowsingContext& aRequestingContext);
|
||||||
|
|
||||||
// Find a browsing context in the subtree rooted at 'this' Doesn't
|
// Find a browsing context in the subtree rooted at 'this' Doesn't
|
||||||
// consider the special names, '_self', '_parent', '_top', or
|
// consider the special names, '_self', '_parent', '_top', or
|
||||||
// '_blank'.
|
// '_blank'. Performs access control checks with regard to
|
||||||
//
|
// 'aRequestingContext'.
|
||||||
// If passed, performs access control checks with regard to
|
|
||||||
// 'aRequestingContext', otherwise performs no access checks.
|
|
||||||
BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
|
BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
|
||||||
WindowGlobalChild* aRequestingWindow);
|
BrowsingContext& aRequestingContext);
|
||||||
|
|
||||||
// Find the special browsing context if aName is '_self', '_parent',
|
|
||||||
// '_top', but not '_blank'. The latter is handled in FindWithName
|
|
||||||
BrowsingContext* FindWithSpecialName(const nsAString& aName,
|
|
||||||
WindowGlobalChild& aRequestingWindow);
|
|
||||||
|
|
||||||
nsISupports* GetParentObject() const;
|
nsISupports* GetParentObject() const;
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext* aCx,
|
||||||
@ -786,6 +791,9 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||||||
BrowsingContextGroup* aGroup,
|
BrowsingContextGroup* aGroup,
|
||||||
ContentParent* aOriginProcess);
|
ContentParent* aOriginProcess);
|
||||||
|
|
||||||
|
// Performs access control to check that 'this' can access 'aTarget'.
|
||||||
|
bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
|
||||||
|
|
||||||
bool IsSandboxedFrom(BrowsingContext* aTarget);
|
bool IsSandboxedFrom(BrowsingContext* aTarget);
|
||||||
|
|
||||||
// The runnable will be called once there is idle time, or the top level
|
// The runnable will be called once there is idle time, or the top level
|
||||||
@ -956,6 +964,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||||||
// parent WC changes.
|
// parent WC changes.
|
||||||
void RecomputeCanExecuteScripts();
|
void RecomputeCanExecuteScripts();
|
||||||
|
|
||||||
|
// Find the special browsing context if aName is '_self', '_parent',
|
||||||
|
// '_top', but not '_blank'. The latter is handled in FindWithName
|
||||||
|
BrowsingContext* FindWithSpecialName(const nsAString& aName,
|
||||||
|
BrowsingContext& aRequestingContext);
|
||||||
|
|
||||||
// Is it early enough in the BrowsingContext's lifecycle that it is still
|
// Is it early enough in the BrowsingContext's lifecycle that it is still
|
||||||
// OK to set OriginAttributes?
|
// OK to set OriginAttributes?
|
||||||
bool CanSetOriginAttributes();
|
bool CanSetOriginAttributes();
|
||||||
|
@ -1438,6 +1438,61 @@ nsDOMNavigationTiming* nsDocShell::GetNavigationTiming() const {
|
|||||||
return mTiming;
|
return mTiming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bug 13871: Prevent frameset spoofing
|
||||||
|
//
|
||||||
|
// This routine answers: 'Is origin's document from same domain as
|
||||||
|
// target's document?'
|
||||||
|
//
|
||||||
|
// file: uris are considered the same domain for the purpose of
|
||||||
|
// frame navigation regardless of script accessibility (bug 420425)
|
||||||
|
//
|
||||||
|
/* static */
|
||||||
|
bool nsDocShell::ValidateOrigin(BrowsingContext* aOrigin,
|
||||||
|
BrowsingContext* aTarget) {
|
||||||
|
nsIDocShell* originDocShell = aOrigin->GetDocShell();
|
||||||
|
MOZ_ASSERT(originDocShell, "originDocShell must not be null");
|
||||||
|
Document* originDocument = originDocShell->GetDocument();
|
||||||
|
NS_ENSURE_TRUE(originDocument, false);
|
||||||
|
|
||||||
|
nsIDocShell* targetDocShell = aTarget->GetDocShell();
|
||||||
|
MOZ_ASSERT(targetDocShell, "targetDocShell must not be null");
|
||||||
|
Document* targetDocument = targetDocShell->GetDocument();
|
||||||
|
NS_ENSURE_TRUE(targetDocument, false);
|
||||||
|
|
||||||
|
bool equal;
|
||||||
|
nsresult rv = originDocument->NodePrincipal()->Equals(
|
||||||
|
targetDocument->NodePrincipal(), &equal);
|
||||||
|
if (NS_SUCCEEDED(rv) && equal) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Not strictly equal, special case if both are file: uris
|
||||||
|
nsCOMPtr<nsIURI> originURI;
|
||||||
|
nsCOMPtr<nsIURI> targetURI;
|
||||||
|
nsCOMPtr<nsIURI> innerOriginURI;
|
||||||
|
nsCOMPtr<nsIURI> innerTargetURI;
|
||||||
|
|
||||||
|
// Casting to BasePrincipal, as we can't get InnerMost URI otherwise
|
||||||
|
auto* originDocumentBasePrincipal =
|
||||||
|
BasePrincipal::Cast(originDocument->NodePrincipal());
|
||||||
|
|
||||||
|
rv = originDocumentBasePrincipal->GetURI(getter_AddRefs(originURI));
|
||||||
|
if (NS_SUCCEEDED(rv) && originURI) {
|
||||||
|
innerOriginURI = NS_GetInnermostURI(originURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* targetDocumentBasePrincipal =
|
||||||
|
BasePrincipal::Cast(targetDocument->NodePrincipal());
|
||||||
|
|
||||||
|
rv = targetDocumentBasePrincipal->GetURI(getter_AddRefs(targetURI));
|
||||||
|
if (NS_SUCCEEDED(rv) && targetURI) {
|
||||||
|
innerTargetURI = NS_GetInnermostURI(targetURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
return innerOriginURI && innerTargetURI && SchemeIsFile(innerOriginURI) &&
|
||||||
|
SchemeIsFile(innerTargetURI);
|
||||||
|
}
|
||||||
|
|
||||||
nsPresContext* nsDocShell::GetEldestPresContext() {
|
nsPresContext* nsDocShell::GetEldestPresContext() {
|
||||||
nsIContentViewer* viewer = mContentViewer;
|
nsIContentViewer* viewer = mContentViewer;
|
||||||
while (viewer) {
|
while (viewer) {
|
||||||
@ -8444,11 +8499,7 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) {
|
|||||||
aLoadState->Target().LowerCaseEqualsLiteral("_self") ||
|
aLoadState->Target().LowerCaseEqualsLiteral("_self") ||
|
||||||
aLoadState->Target().LowerCaseEqualsLiteral("_parent") ||
|
aLoadState->Target().LowerCaseEqualsLiteral("_parent") ||
|
||||||
aLoadState->Target().LowerCaseEqualsLiteral("_top")) {
|
aLoadState->Target().LowerCaseEqualsLiteral("_top")) {
|
||||||
Document* document = GetDocument();
|
targetContext = mBrowsingContext->FindWithName(
|
||||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
|
||||||
WindowGlobalChild* wgc = document->GetWindowGlobalChild();
|
|
||||||
NS_ENSURE_TRUE(wgc, NS_ERROR_FAILURE);
|
|
||||||
targetContext = wgc->FindBrowsingContextWithName(
|
|
||||||
aLoadState->Target(), /* aUseEntryGlobalForAccessCheck */ false);
|
aLoadState->Target(), /* aUseEntryGlobalForAccessCheck */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +558,11 @@ class nsDocShell final : public nsDocLoader,
|
|||||||
nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext,
|
nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext,
|
||||||
uint64_t aContentWindowID);
|
uint64_t aContentWindowID);
|
||||||
|
|
||||||
|
// Security check to prevent frameset spoofing. See comments at
|
||||||
|
// implementation site.
|
||||||
|
static bool ValidateOrigin(mozilla::dom::BrowsingContext* aOrigin,
|
||||||
|
mozilla::dom::BrowsingContext* aTarget);
|
||||||
|
|
||||||
static inline uint32_t PRTimeToSeconds(PRTime aTimeUsec) {
|
static inline uint32_t PRTimeToSeconds(PRTime aTimeUsec) {
|
||||||
return uint32_t(aTimeUsec / PR_USEC_PER_SEC);
|
return uint32_t(aTimeUsec / PR_USEC_PER_SEC);
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,12 @@ add_task(async function() {
|
|||||||
// wish to confirm that targeting is able to find
|
// wish to confirm that targeting is able to find
|
||||||
// appropriate browsing contexts.
|
// appropriate browsing contexts.
|
||||||
|
|
||||||
// WindowGlobalChild.findBrowsingContextWithName requires access
|
// BrowsingContext.findWithName requires access checks, which
|
||||||
// checks, which can only be performed in the process of the accessor
|
// can only be performed in the process of the accessor BC's
|
||||||
// WindowGlobalChild.
|
// docShell.
|
||||||
function findWithName(bc, name) {
|
function findWithName(bc, name) {
|
||||||
return content.SpecialPowers.spawn(bc, [name], name => {
|
return content.SpecialPowers.spawn(bc, [bc, name], (bc, name) => {
|
||||||
return content.windowGlobalChild.findBrowsingContextWithName(
|
return bc.findWithName(name);
|
||||||
name
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3966,11 +3966,9 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {
|
|||||||
already_AddRefed<BrowsingContext> nsGlobalWindowOuter::GetChildWindow(
|
already_AddRefed<BrowsingContext> nsGlobalWindowOuter::GetChildWindow(
|
||||||
const nsAString& aName) {
|
const nsAString& aName) {
|
||||||
NS_ENSURE_TRUE(mBrowsingContext, nullptr);
|
NS_ENSURE_TRUE(mBrowsingContext, nullptr);
|
||||||
NS_ENSURE_TRUE(mInnerWindow, nullptr);
|
|
||||||
NS_ENSURE_TRUE(mInnerWindow->GetWindowGlobalChild(), nullptr);
|
|
||||||
|
|
||||||
return do_AddRef(mBrowsingContext->FindChildWithName(
|
return do_AddRef(
|
||||||
aName, *mInnerWindow->GetWindowGlobalChild()));
|
mBrowsingContext->FindChildWithName(aName, *mBrowsingContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsGlobalWindowOuter::DispatchCustomEvent(
|
bool nsGlobalWindowOuter::DispatchCustomEvent(
|
||||||
@ -4038,10 +4036,7 @@ bool nsGlobalWindowOuter::WindowExists(const nsAString& aName,
|
|||||||
aName.LowerCaseEqualsLiteral("_parent");
|
aName.LowerCaseEqualsLiteral("_parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WindowGlobalChild* wgc = mInnerWindow->GetWindowGlobalChild()) {
|
return !!mBrowsingContext->FindWithName(aName, aLookForCallerOnJSStack);
|
||||||
return wgc->FindBrowsingContextWithName(aName, aLookForCallerOnJSStack);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIWidget> nsGlobalWindowOuter::GetMainWidget() {
|
already_AddRefed<nsIWidget> nsGlobalWindowOuter::GetMainWidget() {
|
||||||
|
@ -71,6 +71,9 @@ interface BrowsingContext {
|
|||||||
|
|
||||||
sequence<BrowsingContext> getAllBrowsingContextsInSubtree();
|
sequence<BrowsingContext> getAllBrowsingContextsInSubtree();
|
||||||
|
|
||||||
|
BrowsingContext? findChildWithName(DOMString name, BrowsingContext accessor);
|
||||||
|
BrowsingContext? findWithName(DOMString name);
|
||||||
|
|
||||||
readonly attribute DOMString name;
|
readonly attribute DOMString name;
|
||||||
|
|
||||||
readonly attribute BrowsingContext? parent;
|
readonly attribute BrowsingContext? parent;
|
||||||
|
@ -177,8 +177,6 @@ interface WindowGlobalChild {
|
|||||||
|
|
||||||
static WindowGlobalChild? getByInnerWindowId(unsigned long long innerWIndowId);
|
static WindowGlobalChild? getByInnerWindowId(unsigned long long innerWIndowId);
|
||||||
|
|
||||||
BrowsingContext? findBrowsingContextWithName(DOMString name);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or create the JSWindowActor with the given name.
|
* Get or create the JSWindowActor with the given name.
|
||||||
*
|
*
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
#include "nsIBrowserDOMWindow.h"
|
#include "nsIBrowserDOMWindow.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIDocShellTreeOwner.h"
|
|
||||||
#include "nsIDOMChromeWindow.h"
|
#include "nsIDOMChromeWindow.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIBrowser.h"
|
#include "nsIBrowser.h"
|
||||||
@ -328,33 +327,25 @@ void GeckoViewOpenWindow(const ClientOpenWindowArgsParsed& aArgsValidated,
|
|||||||
promiseResult->Then(
|
promiseResult->Then(
|
||||||
GetMainThreadSerialEventTarget(), __func__,
|
GetMainThreadSerialEventTarget(), __func__,
|
||||||
[aArgsValidated, promise](nsString sessionId) {
|
[aArgsValidated, promise](nsString sessionId) {
|
||||||
// Retrieve the primary content BrowsingContext using the GeckoSession
|
|
||||||
// ID. The chrome window is named the same as the ID of the GeckoSession
|
|
||||||
// it is associated with.
|
|
||||||
RefPtr<BrowsingContext> browsingContext;
|
|
||||||
nsresult rv = [&sessionId, &browsingContext]() -> nsresult {
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIWindowWatcher> wwatch =
|
nsCOMPtr<nsIWindowWatcher> wwatch =
|
||||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
nsCOMPtr<mozIDOMWindowProxy> chromeWindow;
|
|
||||||
rv = wwatch->GetWindowByName(sessionId, getter_AddRefs(chromeWindow));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(chromeWindow, NS_ERROR_FAILURE);
|
|
||||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner =
|
|
||||||
nsPIDOMWindowOuter::From(chromeWindow)->GetTreeOwner();
|
|
||||||
NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
|
|
||||||
rv = treeOwner->GetPrimaryContentBrowsingContext(
|
|
||||||
getter_AddRefs(browsingContext));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(browsingContext, NS_ERROR_FAILURE);
|
|
||||||
return NS_OK;
|
|
||||||
}();
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
promise->Reject(rv, __func__);
|
promise->Reject(rv, __func__);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve the browsing context by using the GeckoSession ID. The
|
||||||
|
// window is named the same as the ID of the GeckoSession it is
|
||||||
|
// associated with.
|
||||||
|
RefPtr<BrowsingContext> browsingContext =
|
||||||
|
static_cast<nsWindowWatcher*>(wwatch.get())
|
||||||
|
->GetBrowsingContextByName(sessionId, false, nullptr);
|
||||||
|
if (NS_WARN_IF(!browsingContext)) {
|
||||||
|
promise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
WaitForLoad(aArgsValidated, browsingContext, promise);
|
WaitForLoad(aArgsValidated, browsingContext, promise);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
},
|
},
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
#include "mozilla/dom/JSActorService.h"
|
#include "mozilla/dom/JSActorService.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsIURIMutator.h"
|
#include "nsIURIMutator.h"
|
||||||
#include "nsURLHelper.h"
|
|
||||||
|
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
using namespace mozilla::dom::ipc;
|
using namespace mozilla::dom::ipc;
|
||||||
@ -642,169 +641,6 @@ bool WindowGlobalChild::SameOriginWithTop() {
|
|||||||
return IsSameOriginWith(WindowContext()->TopWindowContext());
|
return IsSameOriginWith(WindowContext()->TopWindowContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
// For historical context, see:
|
|
||||||
//
|
|
||||||
// Bug 13871: Prevent frameset spoofing
|
|
||||||
// Bug 103638: Targets with same name in different windows open in wrong
|
|
||||||
// window with javascript
|
|
||||||
// Bug 408052: Adopt "ancestor" frame navigation policy
|
|
||||||
// Bug 1570207: Refactor logic to rely on BrowsingContextGroups to enforce
|
|
||||||
// origin attribute isolation
|
|
||||||
// Bug 1810619: Crash at null in nsDocShell::ValidateOrigin
|
|
||||||
bool WindowGlobalChild::CanNavigate(dom::BrowsingContext* aTarget,
|
|
||||||
bool aConsiderOpener) {
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(WindowContext()->Group() == aTarget->Group(),
|
|
||||||
"A WindowGlobalChild should never try to navigate a "
|
|
||||||
"BrowsingContext from another group");
|
|
||||||
|
|
||||||
auto isFileScheme = [](nsIPrincipal* aPrincipal) -> bool {
|
|
||||||
// NOTE: This code previously checked for a file scheme using
|
|
||||||
// `nsIPrincipal::GetURI()` combined with `NS_GetInnermostURI`. We no longer
|
|
||||||
// use GetURI, as it has been deprecated, and it makes more sense to take
|
|
||||||
// advantage of the pre-computed origin, which will already use the
|
|
||||||
// innermost URI (bug 1810619)
|
|
||||||
nsAutoCString origin, scheme;
|
|
||||||
return NS_SUCCEEDED(aPrincipal->GetOriginNoSuffix(origin)) &&
|
|
||||||
NS_SUCCEEDED(net_ExtractURLScheme(origin, scheme)) &&
|
|
||||||
scheme == "file"_ns;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A frame can navigate itself and its own root.
|
|
||||||
if (aTarget == BrowsingContext() || aTarget == BrowsingContext()->Top()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the target frame doesn't yet have a WindowContext, start checking
|
|
||||||
// principals from its direct ancestor instead. It would inherit its principal
|
|
||||||
// from this document upon creation.
|
|
||||||
dom::WindowContext* initialWc = aTarget->GetCurrentWindowContext();
|
|
||||||
if (!initialWc) {
|
|
||||||
initialWc = aTarget->GetParentWindowContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A frame can navigate any frame with a same-origin ancestor.
|
|
||||||
bool isFileDocument = isFileScheme(DocumentPrincipal());
|
|
||||||
for (dom::WindowContext* wc = initialWc; wc;
|
|
||||||
wc = wc->GetParentWindowContext()) {
|
|
||||||
dom::WindowGlobalChild* wgc = wc->GetWindowGlobalChild();
|
|
||||||
if (!wgc) {
|
|
||||||
continue; // out-of process, so not same-origin.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DocumentPrincipal()->Equals(wgc->DocumentPrincipal())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not strictly equal, special case if both are file: URIs.
|
|
||||||
//
|
|
||||||
// file: URIs are considered the same domain for the purpose of frame
|
|
||||||
// navigation, regardless of script accessibility (bug 420425).
|
|
||||||
if (isFileDocument && isFileScheme(wgc->DocumentPrincipal())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the target is a top-level document, a frame can navigate it if it can
|
|
||||||
// navigate its opener.
|
|
||||||
if (aConsiderOpener && !aTarget->GetParent()) {
|
|
||||||
if (RefPtr<dom::BrowsingContext> opener = aTarget->GetOpener()) {
|
|
||||||
return CanNavigate(opener, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindWithName follows the rules for choosing a browsing context,
|
|
||||||
// with the exception of sandboxing for iframes. The implementation
|
|
||||||
// for arbitrarily choosing between two browsing contexts with the
|
|
||||||
// same name is as follows:
|
|
||||||
//
|
|
||||||
// 1) The start browsing context, i.e. 'this'
|
|
||||||
// 2) Descendants in insertion order
|
|
||||||
// 3) The parent
|
|
||||||
// 4) Siblings and their children, both in insertion order
|
|
||||||
// 5) After this we iteratively follow the parent chain, repeating 3
|
|
||||||
// and 4 until
|
|
||||||
// 6) If there is no parent, consider all other top level browsing
|
|
||||||
// contexts and their children, both in insertion order
|
|
||||||
//
|
|
||||||
// See
|
|
||||||
// https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
|
|
||||||
dom::BrowsingContext* WindowGlobalChild::FindBrowsingContextWithName(
|
|
||||||
const nsAString& aName, bool aUseEntryGlobalForAccessCheck) {
|
|
||||||
RefPtr<WindowGlobalChild> requestingContext = this;
|
|
||||||
if (aUseEntryGlobalForAccessCheck) {
|
|
||||||
if (nsGlobalWindowInner* caller = nsContentUtils::EntryInnerWindow()) {
|
|
||||||
if (caller->GetBrowsingContextGroup() == WindowContext()->Group()) {
|
|
||||||
requestingContext = caller->GetWindowGlobalChild();
|
|
||||||
} else {
|
|
||||||
MOZ_RELEASE_ASSERT(caller->GetPrincipal()->IsSystemPrincipal(),
|
|
||||||
"caller must be either same-group or system");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(requestingContext, "must have a requestingContext");
|
|
||||||
|
|
||||||
dom::BrowsingContext* found = nullptr;
|
|
||||||
if (aName.IsEmpty()) {
|
|
||||||
// You can't find a browsing context with an empty name.
|
|
||||||
found = nullptr;
|
|
||||||
} else if (aName.LowerCaseEqualsLiteral("_blank")) {
|
|
||||||
// Just return null. Caller must handle creating a new window with
|
|
||||||
// a blank name.
|
|
||||||
found = nullptr;
|
|
||||||
} else if (nsContentUtils::IsSpecialName(aName)) {
|
|
||||||
found = BrowsingContext()->FindWithSpecialName(aName, *requestingContext);
|
|
||||||
} else if (dom::BrowsingContext* child =
|
|
||||||
BrowsingContext()->FindWithNameInSubtree(aName,
|
|
||||||
requestingContext)) {
|
|
||||||
found = child;
|
|
||||||
} else {
|
|
||||||
dom::WindowContext* current = WindowContext();
|
|
||||||
|
|
||||||
do {
|
|
||||||
Span<RefPtr<dom::BrowsingContext>> siblings;
|
|
||||||
dom::WindowContext* parent = current->GetParentWindowContext();
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
// We've reached the root of the tree, consider browsing
|
|
||||||
// contexts in the same browsing context group.
|
|
||||||
siblings = WindowContext()->Group()->Toplevels();
|
|
||||||
} else if (dom::BrowsingContext* bc = parent->GetBrowsingContext();
|
|
||||||
bc && bc->NameEquals(aName) &&
|
|
||||||
requestingContext->CanNavigate(bc) && bc->IsTargetable()) {
|
|
||||||
found = bc;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
siblings = parent->NonSyntheticChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (dom::BrowsingContext* sibling : siblings) {
|
|
||||||
if (sibling == current->GetBrowsingContext()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dom::BrowsingContext* relative =
|
|
||||||
sibling->FindWithNameInSubtree(aName, requestingContext)) {
|
|
||||||
found = relative;
|
|
||||||
// Breaks the outer loop
|
|
||||||
parent = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current = parent;
|
|
||||||
} while (current);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers should perform access control checks, which means that we
|
|
||||||
// only need to assert that we can access found.
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!found || requestingContext->CanNavigate(found));
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowGlobalChild::UnblockBFCacheFor(BFCacheStatus aStatus) {
|
void WindowGlobalChild::UnblockBFCacheFor(BFCacheStatus aStatus) {
|
||||||
SendUpdateBFCacheStatus(0, aStatus);
|
SendUpdateBFCacheStatus(0, aStatus);
|
||||||
}
|
}
|
||||||
|
@ -123,23 +123,6 @@ class WindowGlobalChild final : public WindowGlobalActor,
|
|||||||
|
|
||||||
bool SameOriginWithTop();
|
bool SameOriginWithTop();
|
||||||
|
|
||||||
// Returns `true` if this WindowGlobal is allowed to navigate the given
|
|
||||||
// BrowsingContext. BrowsingContexts which are currently out-of-process are
|
|
||||||
// supported, and assumed to be cross-origin.
|
|
||||||
//
|
|
||||||
// The given BrowsingContext must be in the same BrowsingContextGroup as this
|
|
||||||
// WindowGlobal.
|
|
||||||
bool CanNavigate(dom::BrowsingContext* aTarget, bool aConsiderOpener = true);
|
|
||||||
|
|
||||||
// Using the rules for choosing a browsing context we try to find
|
|
||||||
// the browsing context with the given name in the set of
|
|
||||||
// transitively reachable browsing contexts. Performs access control
|
|
||||||
// checks with regard to this.
|
|
||||||
// See
|
|
||||||
// https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name.
|
|
||||||
dom::BrowsingContext* FindBrowsingContextWithName(
|
|
||||||
const nsAString& aName, bool aUseEntryGlobalForAccessCheck = true);
|
|
||||||
|
|
||||||
nsISupports* GetParentObject();
|
nsISupports* GetParentObject();
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
@ -272,6 +272,7 @@ public final class GeckoRuntime implements Parcelable {
|
|||||||
if (!session.isOpen()) {
|
if (!session.isOpen()) {
|
||||||
session.open(sRuntime);
|
session.open(sRuntime);
|
||||||
}
|
}
|
||||||
|
session.loadUri(url);
|
||||||
result.complete(session.getId());
|
result.complete(session.getId());
|
||||||
} else {
|
} else {
|
||||||
result.complete(null);
|
result.complete(null);
|
||||||
|
@ -193,7 +193,10 @@ class GeckoViewNavigation extends GeckoViewModule {
|
|||||||
|
|
||||||
let triggeringPrincipal, referrerInfo, csp;
|
let triggeringPrincipal, referrerInfo, csp;
|
||||||
if (referrerSessionId) {
|
if (referrerSessionId) {
|
||||||
const referrerWindow = Services.ww.getWindowByName(referrerSessionId);
|
const referrerWindow = Services.ww.getWindowByName(
|
||||||
|
referrerSessionId,
|
||||||
|
this.window
|
||||||
|
);
|
||||||
triggeringPrincipal = referrerWindow.browser.contentPrincipal;
|
triggeringPrincipal = referrerWindow.browser.contentPrincipal;
|
||||||
csp = referrerWindow.browser.csp;
|
csp = referrerWindow.browser.csp;
|
||||||
|
|
||||||
|
@ -137,17 +137,18 @@ interface nsIWindowWatcher : nsISupports {
|
|||||||
nsIWebBrowserChrome getChromeForWindow(in mozIDOMWindowProxy aWindow);
|
nsIWebBrowserChrome getChromeForWindow(in mozIDOMWindowProxy aWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieve an existing chrome window (or frame).
|
Retrieve an existing window (or frame).
|
||||||
@param aTargetName the window name
|
@param aTargetName the window name
|
||||||
|
@param aCurrentWindow a starting point in the window hierarchy to
|
||||||
Note: This method will not consider special names like "_blank", "_top",
|
begin the search. If null, each toplevel window
|
||||||
"_self", or "_parent", as there is no reference window.
|
will be searched.
|
||||||
|
|
||||||
Note: This method will search all open windows for any window or
|
Note: This method will search all open windows for any window or
|
||||||
frame with the given window name. Make sure you understand the
|
frame with the given window name. Make sure you understand the
|
||||||
security implications of this before using this method!
|
security implications of this before using this method!
|
||||||
*/
|
*/
|
||||||
mozIDOMWindowProxy getWindowByName(in AString aTargetName);
|
mozIDOMWindowProxy getWindowByName(in AString aTargetName,
|
||||||
|
in mozIDOMWindowProxy aCurrentWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieves the active window from the focus manager.
|
Retrieves the active window from the focus manager.
|
||||||
|
@ -71,7 +71,6 @@
|
|||||||
#include "mozilla/dom/BrowserParent.h"
|
#include "mozilla/dom/BrowserParent.h"
|
||||||
#include "mozilla/dom/BrowserHost.h"
|
#include "mozilla/dom/BrowserHost.h"
|
||||||
#include "mozilla/dom/DocGroup.h"
|
#include "mozilla/dom/DocGroup.h"
|
||||||
#include "mozilla/dom/WindowGlobalChild.h"
|
|
||||||
#include "mozilla/dom/SessionStorageManager.h"
|
#include "mozilla/dom/SessionStorageManager.h"
|
||||||
#include "nsIAppWindow.h"
|
#include "nsIAppWindow.h"
|
||||||
#include "nsIXULBrowserWindow.h"
|
#include "nsIXULBrowserWindow.h"
|
||||||
@ -697,35 +696,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
|||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no parent, consider it chrome when running in the parent process.
|
|
||||||
bool hasChromeParent = !XRE_IsContentProcess();
|
|
||||||
if (aParent) {
|
|
||||||
// Check if the parent document has chrome privileges.
|
|
||||||
hasChromeParent = parentDoc && nsContentUtils::IsChromeDoc(parentDoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCallerChrome = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
|
|
||||||
|
|
||||||
// try to find an extant browsing context with the given name
|
// try to find an extant browsing context with the given name
|
||||||
if (!name.IsEmpty() &&
|
targetBC = GetBrowsingContextByName(name, aForceNoOpener, parentBC);
|
||||||
(!aForceNoOpener || nsContentUtils::IsSpecialName(name))) {
|
|
||||||
if (parentInnerWin && parentInnerWin->GetWindowGlobalChild()) {
|
|
||||||
// If we have a parent window, perform the look-up relative to the parent
|
|
||||||
// inner window.
|
|
||||||
targetBC =
|
|
||||||
parentInnerWin->GetWindowGlobalChild()->FindBrowsingContextWithName(
|
|
||||||
name);
|
|
||||||
} else if (hasChromeParent && isCallerChrome &&
|
|
||||||
!nsContentUtils::IsSpecialName(name)) {
|
|
||||||
// Otherwise, if this call is from chrome, perform the lookup relative
|
|
||||||
// to the system group.
|
|
||||||
nsCOMPtr<mozIDOMWindowProxy> chromeWindow;
|
|
||||||
MOZ_ALWAYS_SUCCEEDS(GetWindowByName(name, getter_AddRefs(chromeWindow)));
|
|
||||||
if (chromeWindow) {
|
|
||||||
targetBC = nsPIDOMWindowOuter::From(chromeWindow)->GetBrowsingContext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do sandbox checks here, instead of waiting until nsIDocShell::LoadURI.
|
// Do sandbox checks here, instead of waiting until nsIDocShell::LoadURI.
|
||||||
// The state of the window can change before this call and if we are blocked
|
// The state of the window can change before this call and if we are blocked
|
||||||
@ -742,6 +714,15 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
|||||||
|
|
||||||
// no extant window? make a new one.
|
// no extant window? make a new one.
|
||||||
|
|
||||||
|
// If no parent, consider it chrome when running in the parent process.
|
||||||
|
bool hasChromeParent = !XRE_IsContentProcess();
|
||||||
|
if (aParent) {
|
||||||
|
// Check if the parent document has chrome privileges.
|
||||||
|
hasChromeParent = parentDoc && nsContentUtils::IsChromeDoc(parentDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCallerChrome = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
|
||||||
|
|
||||||
CSSToDesktopScale cssToDesktopScale(1.0);
|
CSSToDesktopScale cssToDesktopScale(1.0);
|
||||||
if (nsCOMPtr<nsIBaseWindow> win = do_QueryInterface(parentDocShell)) {
|
if (nsCOMPtr<nsIBaseWindow> win = do_QueryInterface(parentDocShell)) {
|
||||||
cssToDesktopScale = win->GetUnscaledCSSToDesktopScale();
|
cssToDesktopScale = win->GetUnscaledCSSToDesktopScale();
|
||||||
@ -1713,6 +1694,7 @@ nsWindowWatcher::GetChromeForWindow(mozIDOMWindowProxy* aWindow,
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsWindowWatcher::GetWindowByName(const nsAString& aTargetName,
|
nsWindowWatcher::GetWindowByName(const nsAString& aTargetName,
|
||||||
|
mozIDOMWindowProxy* aCurrentWindow,
|
||||||
mozIDOMWindowProxy** aResult) {
|
mozIDOMWindowProxy** aResult) {
|
||||||
if (!aResult) {
|
if (!aResult) {
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
@ -1720,22 +1702,17 @@ nsWindowWatcher::GetWindowByName(const nsAString& aTargetName,
|
|||||||
|
|
||||||
*aResult = nullptr;
|
*aResult = nullptr;
|
||||||
|
|
||||||
// We won't be able to find any windows with a special or empty name.
|
BrowsingContext* currentContext =
|
||||||
if (aTargetName.IsEmpty() || nsContentUtils::IsSpecialName(aTargetName)) {
|
aCurrentWindow
|
||||||
return NS_OK;
|
? nsPIDOMWindowOuter::From(aCurrentWindow)->GetBrowsingContext()
|
||||||
}
|
: nullptr;
|
||||||
|
|
||||||
|
RefPtr<BrowsingContext> context =
|
||||||
|
GetBrowsingContextByName(aTargetName, false, currentContext);
|
||||||
|
|
||||||
// Search each toplevel in the chrome BrowsingContextGroup for a window with
|
|
||||||
// the given name.
|
|
||||||
for (const RefPtr<BrowsingContext>& toplevel :
|
|
||||||
BrowsingContextGroup::GetChromeGroup()->Toplevels()) {
|
|
||||||
BrowsingContext* context =
|
|
||||||
toplevel->FindWithNameInSubtree(aTargetName, nullptr);
|
|
||||||
if (context) {
|
if (context) {
|
||||||
*aResult = do_AddRef(context->GetDOMWindow()).take();
|
*aResult = do_AddRef(context->GetDOMWindow()).take();
|
||||||
MOZ_ASSERT(*aResult);
|
MOZ_ASSERT(*aResult);
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -2052,6 +2029,36 @@ uint32_t nsWindowWatcher::CalculateChromeFlagsForSystem(
|
|||||||
return chromeFlags;
|
return chromeFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<BrowsingContext> nsWindowWatcher::GetBrowsingContextByName(
|
||||||
|
const nsAString& aName, bool aForceNoOpener,
|
||||||
|
BrowsingContext* aCurrentContext) {
|
||||||
|
if (aName.IsEmpty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aForceNoOpener && !nsContentUtils::IsSpecialName(aName)) {
|
||||||
|
// Ignore all other names in the noopener case.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<BrowsingContext> foundContext;
|
||||||
|
if (aCurrentContext) {
|
||||||
|
foundContext = aCurrentContext->FindWithName(aName);
|
||||||
|
} else if (!nsContentUtils::IsSpecialName(aName)) {
|
||||||
|
// If we are looking for an item and we don't have a docshell we are
|
||||||
|
// checking on, let's just look in the chrome browsing context group!
|
||||||
|
for (RefPtr<BrowsingContext> toplevel :
|
||||||
|
BrowsingContextGroup::GetChromeGroup()->Toplevels()) {
|
||||||
|
foundContext = toplevel->FindWithNameInSubtree(aName, *toplevel);
|
||||||
|
if (foundContext) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundContext.forget();
|
||||||
|
}
|
||||||
|
|
||||||
// public static
|
// public static
|
||||||
bool nsWindowWatcher::HaveSpecifiedSize(const WindowFeatures& features) {
|
bool nsWindowWatcher::HaveSpecifiedSize(const WindowFeatures& features) {
|
||||||
return CalcSizeSpec(features, false, CSSToDesktopScale()).SizeSpecified();
|
return CalcSizeSpec(features, false, CSSToDesktopScale()).SizeSpecified();
|
||||||
|
@ -56,6 +56,13 @@ class nsWindowWatcher : public nsIWindowWatcher,
|
|||||||
uint32_t aChromeFlags,
|
uint32_t aChromeFlags,
|
||||||
bool aCalledFromJS, bool aIsForPrinting);
|
bool aCalledFromJS, bool aIsForPrinting);
|
||||||
|
|
||||||
|
// Will first look for a caller on the JS stack, and then fall back on
|
||||||
|
// aCurrentContext if it can't find one.
|
||||||
|
// It also knows to not look for things if aForceNoOpener is set.
|
||||||
|
already_AddRefed<mozilla::dom::BrowsingContext> GetBrowsingContextByName(
|
||||||
|
const nsAString& aName, bool aForceNoOpener,
|
||||||
|
mozilla::dom::BrowsingContext* aCurrentContext);
|
||||||
|
|
||||||
static bool HaveSpecifiedSize(const mozilla::dom::WindowFeatures& features);
|
static bool HaveSpecifiedSize(const mozilla::dom::WindowFeatures& features);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -381,7 +381,7 @@ const AbuseReporter = {
|
|||||||
* @returns {Window?}
|
* @returns {Window?}
|
||||||
*/
|
*/
|
||||||
getOpenDialog() {
|
getOpenDialog() {
|
||||||
return Services.ww.getWindowByName(DIALOG_WINDOW_NAME);
|
return Services.ww.getWindowByName(DIALOG_WINDOW_NAME, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,7 +188,7 @@ const AbuseReportTestUtils = {
|
|||||||
|
|
||||||
// Returns the currently open abuse report dialog window (if any).
|
// Returns the currently open abuse report dialog window (if any).
|
||||||
getReportDialog() {
|
getReportDialog() {
|
||||||
return Services.ww.getWindowByName("addons-abuse-report-dialog");
|
return Services.ww.getWindowByName("addons-abuse-report-dialog", null);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns the parameters related to the report dialog (if any).
|
// Returns the parameters related to the report dialog (if any).
|
||||||
|
Loading…
Reference in New Issue
Block a user