Backed out 5 changesets (bug 1694993) for bc failure on browser_cross_process_csp_inheritance.js

Backed out changeset 1d21d911b3e7 (bug 1694993)
Backed out changeset 3b412d5fbdcf (bug 1694993)
Backed out changeset c9585ce37fe5 (bug 1694993)
Backed out changeset 05d7cbbfe9e2 (bug 1694993)
Backed out changeset 3821545ab46b (bug 1694993)
This commit is contained in:
Narcis Beleuzu 2022-08-22 20:32:02 +03:00
Родитель bfde821b3b
Коммит 94d309143f
8 изменённых файлов: 185 добавлений и 304 удалений

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

@ -215,4 +215,3 @@ skip-if = !sessionHistoryInParent
support-files = support-files =
file_ship_beforeunload_fired.html file_ship_beforeunload_fired.html
skip-if = !sessionHistoryInParent skip-if = !sessionHistoryInParent
[test_open_javascript_noopener.html]

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

@ -1,44 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script>
add_task(async function test_open_javascript_noopener() {
const topic = "test-javascript-was-run";
function jsuri(version) {
return `javascript:SpecialPowers.notifyObservers(null, "${topic}", "${version}");window.close()`;
}
let seen = [];
function observer(_subject, _topic, data) {
info(`got notification ${data}`);
seen.push(data);
}
SpecialPowers.addObserver(observer, topic);
isDeeply(seen, [], "seen no test notifications");
window.open(jsuri("1"));
// Bounce off the parent process to make sure the JS will have run.
await SpecialPowers.spawnChrome([], () => {});
isDeeply(seen, ["1"], "seen the opener notification");
window.open(jsuri("2"), "", "noopener");
// Bounce off the parent process to make sure the JS will have run.
await SpecialPowers.spawnChrome([], () => {});
isDeeply(seen, ["1"], "didn't get a notification from the noopener popup");
SpecialPowers.removeObserver(observer, topic);
});
</script>
</body>
</html>

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

@ -1756,18 +1756,22 @@ bool nsGlobalWindowOuter::WouldReuseInnerWindow(Document* aNewDocument) {
return false; return false;
} }
void nsGlobalWindowOuter::SetInitialPrincipal( void nsGlobalWindowOuter::SetInitialPrincipalToSubject(
nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP, nsIContentSecurityPolicy* aCSP,
const Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCOEP) { const Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCOEP) {
// First, grab the subject principal.
nsCOMPtr<nsIPrincipal> newWindowPrincipal =
nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
// We should never create windows with an expanded principal. // We should never create windows with an expanded principal.
// If we have a system principal, make sure we're not using it for a content // If we have a system principal, make sure we're not using it for a content
// docshell. // docshell.
// NOTE: Please keep this logic in sync with // NOTE: Please keep this logic in sync with
// nsAppShellService::JustCreateTopWindow // nsAppShellService::JustCreateTopWindow
if (nsContentUtils::IsExpandedPrincipal(aNewWindowPrincipal) || if (nsContentUtils::IsExpandedPrincipal(newWindowPrincipal) ||
(aNewWindowPrincipal->IsSystemPrincipal() && (newWindowPrincipal->IsSystemPrincipal() &&
GetBrowsingContext()->IsContent())) { GetBrowsingContext()->IsContent())) {
aNewWindowPrincipal = nullptr; newWindowPrincipal = nullptr;
} }
// If there's an existing document, bail if it either: // If there's an existing document, bail if it either:
@ -1775,7 +1779,7 @@ void nsGlobalWindowOuter::SetInitialPrincipal(
// (a) is not an initial about:blank document, or // (a) is not an initial about:blank document, or
if (!mDoc->IsInitialDocument()) return; if (!mDoc->IsInitialDocument()) return;
// (b) already has the correct principal. // (b) already has the correct principal.
if (mDoc->NodePrincipal() == aNewWindowPrincipal) return; if (mDoc->NodePrincipal() == newWindowPrincipal) return;
#ifdef DEBUG #ifdef DEBUG
// If we have a document loaded at this point, it had better be about:blank. // If we have a document loaded at this point, it had better be about:blank.
@ -1791,7 +1795,7 @@ void nsGlobalWindowOuter::SetInitialPrincipal(
// Use the subject (or system) principal as the storage principal too until // Use the subject (or system) principal as the storage principal too until
// the new window finishes navigating and gets a real storage principal. // the new window finishes navigating and gets a real storage principal.
nsDocShell::Cast(GetDocShell()) nsDocShell::Cast(GetDocShell())
->CreateAboutBlankContentViewer(aNewWindowPrincipal, aNewWindowPrincipal, ->CreateAboutBlankContentViewer(newWindowPrincipal, newWindowPrincipal,
aCSP, nullptr, aCSP, nullptr,
/* aIsInitialDocument */ true, aCOEP); /* aIsInitialDocument */ true, aCOEP);

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

@ -305,8 +305,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
mozilla::dom::EventTarget* aChromeEventHandler) override; mozilla::dom::EventTarget* aChromeEventHandler) override;
// Outer windows only. // Outer windows only.
virtual void SetInitialPrincipal( virtual void SetInitialPrincipalToSubject(
nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP, nsIContentSecurityPolicy* aCSP,
const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep) const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep)
override; override;

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

@ -880,10 +880,10 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
return mDoc; return mDoc;
} }
// Set the window up with an about:blank document with the given principal and // Set the window up with an about:blank document with the current subject
// potentially a CSP and a COEP. // principal and potentially a CSP and a COEP.
virtual void SetInitialPrincipal( virtual void SetInitialPrincipalToSubject(
nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP, nsIContentSecurityPolicy* aCSP,
const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep) = 0; const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep) = 0;
// Returns an object containing the window's state. This also suspends // Returns an object containing the window's state. This also suspends

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

@ -1,26 +0,0 @@
test(function() {
var popup = window.open("", "sessionStorageTestWindow");
sessionStorage.setItem("FOO", "BAR");
var reopened = window.open("", "sessionStorageTestWindow");
assert_equals(
popup,
reopened,
"window.open with the same name should re-open the same window"
);
assert_equals(
sessionStorage.getItem("FOO"),
"BAR",
"local sessionStorage is correct"
);
assert_equals(
popup.sessionStorage.getItem("FOO"),
null,
"popup sessionStorage is correct"
);
popup.close();
}, "ensure that re-opening a named window doesn't copy sessionStorage");

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

@ -629,10 +629,10 @@ nsresult nsWindowWatcher::OpenWindowInternal(
nsAutoString name; // string version of aName nsAutoString name; // string version of aName
nsCOMPtr<nsIURI> uriToLoad; // from aUrl, if any nsCOMPtr<nsIURI> uriToLoad; // from aUrl, if any
nsCOMPtr<nsIDocShellTreeOwner> nsCOMPtr<nsIDocShellTreeOwner>
parentTreeOwner; // from the parent window, if any parentTreeOwner; // from the parent window, if any
RefPtr<BrowsingContext> targetBC; // from the new window RefPtr<BrowsingContext> newBC; // from the new window
nsCOMPtr<nsPIDOMWindowOuter> parentOuterWin = nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
aParent ? nsPIDOMWindowOuter::From(aParent) : nullptr; aParent ? nsPIDOMWindowOuter::From(aParent) : nullptr;
NS_ENSURE_ARG_POINTER(aResult); NS_ENSURE_ARG_POINTER(aResult);
@ -643,8 +643,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (parentOuterWin) { if (parentWindow) {
parentTreeOwner = parentOuterWin->GetTreeOwner(); parentTreeOwner = parentWindow->GetTreeOwner();
} }
// We expect BrowserParent to have provided us the absolute URI of the window // We expect BrowserParent to have provided us the absolute URI of the window
@ -676,13 +676,9 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
RefPtr<BrowsingContext> parentBC( RefPtr<BrowsingContext> parentBC(
parentOuterWin ? parentOuterWin->GetBrowsingContext() : nullptr); parentWindow ? parentWindow->GetBrowsingContext() : nullptr);
nsCOMPtr<nsIDocShell> parentDocShell(parentBC ? parentBC->GetDocShell() nsCOMPtr<nsIDocShell> parentDocShell(parentBC ? parentBC->GetDocShell()
: nullptr); : nullptr);
RefPtr<Document> parentDoc(parentOuterWin ? parentOuterWin->GetDoc()
: nullptr);
nsCOMPtr<nsPIDOMWindowInner> parentInnerWin(
parentOuterWin ? parentOuterWin->GetCurrentInnerWindow() : nullptr);
// Return null for any attempt to trigger a load from a discarded browsing // Return null for any attempt to trigger a load from a discarded browsing
// context. The spec is non-normative, and doesn't specify what should happen // context. The spec is non-normative, and doesn't specify what should happen
@ -698,18 +694,18 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
// try to find an extant browsing context with the given name // try to find an extant browsing context with the given name
targetBC = GetBrowsingContextByName(name, aForceNoOpener, parentBC); newBC = GetBrowsingContextByName(name, aForceNoOpener, parentBC);
// 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
// because of sandboxing, we wouldn't want that to happen. // because of sandboxing, we wouldn't want that to happen.
if (parentBC && parentBC->IsSandboxedFrom(targetBC)) { if (parentBC && parentBC->IsSandboxedFrom(newBC)) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR; return NS_ERROR_DOM_INVALID_ACCESS_ERR;
} }
// If our target BrowsingContext is still pending initialization, ignore the // If our target BrowsingContext is still pending initialization, ignore the
// navigation request targeting it. // navigation request targeting it.
if (targetBC && NS_WARN_IF(targetBC->GetPendingInitialization())) { if (newBC && NS_WARN_IF(newBC->GetPendingInitialization())) {
return NS_ERROR_ABORT; return NS_ERROR_ABORT;
} }
@ -719,7 +715,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
bool hasChromeParent = !XRE_IsContentProcess(); bool hasChromeParent = !XRE_IsContentProcess();
if (aParent) { if (aParent) {
// Check if the parent document has chrome privileges. // Check if the parent document has chrome privileges.
hasChromeParent = parentDoc && nsContentUtils::IsChromeDoc(parentDoc); Document* doc = parentWindow->GetDoc();
hasChromeParent = doc && nsContentUtils::IsChromeDoc(doc);
} }
bool isCallerChrome = nsContentUtils::LegacyIsCallerChromeOrNativeCode(); bool isCallerChrome = nsContentUtils::LegacyIsCallerChromeOrNativeCode();
@ -811,56 +808,10 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
} }
// Now that the jsapiChromeGuard has been set, fetch the system principal
// potentially configured by it. We want to make sure to respect any principal
// changes imposed by that guard throughout this function.
//
// Note: The check for the current JSContext isn't necessarily sensical.
// It's just designed to preserve old semantics during a mass-conversion
// patch.
// Bug 1498605 verify usages of systemPrincipal here
JSContext* cx = nsContentUtils::GetCurrentJSContext();
nsCOMPtr<nsIPrincipal> subjectPrincipal =
cx ? nsContentUtils::SubjectPrincipal()
: nsContentUtils::GetSystemPrincipal();
MOZ_ASSERT(subjectPrincipal);
nsCOMPtr<nsIPrincipal> newWindowPrincipal;
if (!targetBC) {
if (windowTypeIsChrome) {
// If we are creating a chrome window, we must be called with a system
// principal, and should inherit that for the new chrome window.
MOZ_RELEASE_ASSERT(subjectPrincipal->IsSystemPrincipal(),
"Only system principals can create chrome windows");
newWindowPrincipal = subjectPrincipal;
} else if (nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal)) {
// Don't allow initial about:blank documents to inherit a system or
// expanded principal, instead replace it with a null principal. We can't
// inherit origin attributes from the system principal, so use the parent
// BC if it's available.
if (parentBC) {
newWindowPrincipal = NullPrincipal::CreateWithInheritedAttributes(
parentBC->OriginAttributesRef());
} else {
newWindowPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
}
} else if (aForceNoOpener) {
// If we're opening a new window with noopener, create a new opaque
// principal for the new window, rather than re-using the existing
// principal.
newWindowPrincipal =
NullPrincipal::CreateWithInheritedAttributes(subjectPrincipal);
} else {
// Finally, if there's an opener relationship and it's not a special
// principal, we should inherit that principal for the new window.
newWindowPrincipal = subjectPrincipal;
}
}
// Information used when opening new content windows. This object will be // Information used when opening new content windows. This object will be
// passed through to the inner nsFrameLoader. // passed through to the inner nsFrameLoader.
RefPtr<nsOpenWindowInfo> openWindowInfo; RefPtr<nsOpenWindowInfo> openWindowInfo;
if (!targetBC && !windowTypeIsChrome) { if (!newBC && !windowTypeIsChrome) {
openWindowInfo = new nsOpenWindowInfo(); openWindowInfo = new nsOpenWindowInfo();
openWindowInfo->mForceNoOpener = aForceNoOpener; openWindowInfo->mForceNoOpener = aForceNoOpener;
openWindowInfo->mParent = parentBC; openWindowInfo->mParent = parentBC;
@ -871,12 +822,17 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// want it to match the current remoteness. // want it to match the current remoteness.
openWindowInfo->mIsRemote = XRE_IsContentProcess(); openWindowInfo->mIsRemote = XRE_IsContentProcess();
// Inherit our OriginAttributes from the computed new window principal. // If we have a non-system non-expanded subject principal, we can inherit
MOZ_ASSERT( // our OriginAttributes from it.
newWindowPrincipal && nsCOMPtr<nsIPrincipal> subjectPrincipal =
!nsContentUtils::IsSystemOrExpandedPrincipal(newWindowPrincipal)); nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
openWindowInfo->mOriginAttributes = if (subjectPrincipal &&
newWindowPrincipal->OriginAttributesRef(); !nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal)) {
openWindowInfo->mOriginAttributes =
subjectPrincipal->OriginAttributesRef();
} else if (parentBC) {
openWindowInfo->mOriginAttributes = parentBC->OriginAttributesRef();
}
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
!parentBC || openWindowInfo->mOriginAttributes.EqualsIgnoringFPD( !parentBC || openWindowInfo->mOriginAttributes.EqualsIgnoringFPD(
@ -887,7 +843,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
uint32_t activeDocsSandboxFlags = 0; uint32_t activeDocsSandboxFlags = 0;
nsCOMPtr<nsIContentSecurityPolicy> cspToInheritForAboutBlank; nsCOMPtr<nsIContentSecurityPolicy> cspToInheritForAboutBlank;
Maybe<nsILoadInfo::CrossOriginEmbedderPolicy> coepToInheritForAboutBlank; Maybe<nsILoadInfo::CrossOriginEmbedderPolicy> coepToInheritForAboutBlank;
if (!targetBC) { if (!newBC) {
// We're going to either open up a new window ourselves or ask a // We're going to either open up a new window ourselves or ask a
// nsIWindowProvider for one. In either case, we'll want to set the right // nsIWindowProvider for one. In either case, we'll want to set the right
// name on it. // name on it.
@ -895,20 +851,22 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// If the parent trying to open a new window is sandboxed // If the parent trying to open a new window is sandboxed
// without 'allow-popups', this is not allowed and we fail here. // without 'allow-popups', this is not allowed and we fail here.
if (parentDoc) { if (aParent) {
// Save sandbox flags for copying to new browsing context (docShell). if (Document* doc = parentWindow->GetDoc()) {
activeDocsSandboxFlags = parentDoc->GetSandboxFlags(); // Save sandbox flags for copying to new browsing context (docShell).
activeDocsSandboxFlags = doc->GetSandboxFlags();
if (!aForceNoOpener) { if (!aForceNoOpener) {
cspToInheritForAboutBlank = parentDoc->GetCsp(); cspToInheritForAboutBlank = doc->GetCsp();
coepToInheritForAboutBlank = parentDoc->GetEmbedderPolicy(); coepToInheritForAboutBlank = doc->GetEmbedderPolicy();
} }
// Check to see if this frame is allowed to navigate, but don't check if // Check to see if this frame is allowed to navigate, but don't check if
// we're printing, as that's not a real navigation. // we're printing, as that's not a real navigation.
if (aPrintKind == PRINT_NONE && if (aPrintKind == PRINT_NONE &&
(activeDocsSandboxFlags & SANDBOXED_AUXILIARY_NAVIGATION)) { (activeDocsSandboxFlags & SANDBOXED_AUXILIARY_NAVIGATION)) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR; return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
} }
} }
@ -926,17 +884,17 @@ nsresult nsWindowWatcher::OpenWindowInternal(
rv = provider->ProvideWindow( rv = provider->ProvideWindow(
openWindowInfo, chromeFlags, aCalledFromJS, uriToLoad, name, openWindowInfo, chromeFlags, aCalledFromJS, uriToLoad, name,
featuresStr, aForceNoOpener, aForceNoReferrer, isPopupRequested, featuresStr, aForceNoOpener, aForceNoReferrer, isPopupRequested,
aLoadState, &windowIsNew, getter_AddRefs(targetBC)); aLoadState, &windowIsNew, getter_AddRefs(newBC));
if (NS_SUCCEEDED(rv) && targetBC) { if (NS_SUCCEEDED(rv) && newBC) {
nsCOMPtr<nsIDocShell> newDocShell = targetBC->GetDocShell(); nsCOMPtr<nsIDocShell> newDocShell = newBC->GetDocShell();
// If this is a new window, but it's incompatible with the current // If this is a new window, but it's incompatible with the current
// userContextId, we ignore it and we pretend that nothing has been // userContextId, we ignore it and we pretend that nothing has been
// returned by ProvideWindow. // returned by ProvideWindow.
if (!windowIsNew && newDocShell) { if (!windowIsNew && newDocShell) {
if (!CheckUserContextCompatibility(newDocShell)) { if (!CheckUserContextCompatibility(newDocShell)) {
targetBC = nullptr; newBC = nullptr;
windowIsNew = false; windowIsNew = false;
} }
} }
@ -955,7 +913,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
bool newWindowShouldBeModal = false; bool newWindowShouldBeModal = false;
bool parentIsModal = false; bool parentIsModal = false;
if (!targetBC) { if (!newBC) {
if (XRE_IsContentProcess()) { if (XRE_IsContentProcess()) {
// If our window provider failed to provide a window in the content // If our window provider failed to provide a window in the content
// process, we cannot recover. Reject the window open request and bail. // process, we cannot recover. Reject the window open request and bail.
@ -1009,9 +967,9 @@ nsresult nsWindowWatcher::OpenWindowInternal(
nsCOMPtr<nsIWebBrowserChrome> newChrome; nsCOMPtr<nsIWebBrowserChrome> newChrome;
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow; nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
if (parentOuterWin) { if (parentWindow) {
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow = nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
parentOuterWin->GetInProcessTop(); parentWindow->GetInProcessTop();
if (parentTopWindow) { if (parentTopWindow) {
parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow(); parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow();
} }
@ -1048,53 +1006,53 @@ nsresult nsWindowWatcher::OpenWindowInternal(
if (!newDocShellItem) { if (!newDocShellItem) {
rv = NS_ERROR_FAILURE; rv = NS_ERROR_FAILURE;
} }
targetBC = newDocShellItem->GetBrowsingContext(); newBC = newDocShellItem->GetBrowsingContext();
} }
} }
} }
// better have a window to use by this point // better have a window to use by this point
if (!targetBC) { if (!newBC) {
return rv; return rv;
} }
// If our parent is sandboxed, set it as the one permitted sandboxed navigator // If our parent is sandboxed, set it as the one permitted sandboxed navigator
// on the new window we're opening. // on the new window we're opening.
if (activeDocsSandboxFlags && parentBC) { if (activeDocsSandboxFlags && parentBC) {
MOZ_ALWAYS_SUCCEEDS(targetBC->SetOnePermittedSandboxedNavigator(parentBC)); MOZ_ALWAYS_SUCCEEDS(newBC->SetOnePermittedSandboxedNavigator(parentBC));
} }
if (!aForceNoOpener && parentBC) { if (!aForceNoOpener && parentBC) {
// If we've created a new content window, its opener should have been set // If we've created a new content window, its opener should have been set
// when its BrowsingContext was created, in order to ensure that the context // when its BrowsingContext was created, in order to ensure that the context
// is loaded within the correct BrowsingContextGroup. // is loaded within the correct BrowsingContextGroup.
if (windowIsNew && targetBC->IsContent()) { if (windowIsNew && newBC->IsContent()) {
if (parentBC->IsDiscarded()) { if (parentBC->IsDiscarded()) {
// If the parent BC was discarded in a nested event loop before we got // If the parent BC was discarded in a nested event loop before we got
// to this point, we can't set it as the opener. Ideally we would still // to this point, we can't set it as the opener. Ideally we would still
// set `HadOriginalOpener()` in that case, but that's somewhat // set `HadOriginalOpener()` in that case, but that's somewhat
// nontrivial, and not worth the effort given the nature of the corner // nontrivial, and not worth the effort given the nature of the corner
// case (see comment in `nsFrameLoader::CreateBrowsingContext`. // case (see comment in `nsFrameLoader::CreateBrowsingContext`.
MOZ_RELEASE_ASSERT(targetBC->GetOpenerId() == parentBC->Id() || MOZ_RELEASE_ASSERT(newBC->GetOpenerId() == parentBC->Id() ||
targetBC->GetOpenerId() == 0); newBC->GetOpenerId() == 0);
} else { } else {
MOZ_RELEASE_ASSERT(targetBC->GetOpenerId() == parentBC->Id()); MOZ_RELEASE_ASSERT(newBC->GetOpenerId() == parentBC->Id());
MOZ_RELEASE_ASSERT(targetBC->HadOriginalOpener()); MOZ_RELEASE_ASSERT(newBC->HadOriginalOpener());
} }
} else { } else {
// Update the opener for an existing or chrome BC. // Update the opener for an existing or chrome BC.
targetBC->SetOpener(parentBC); newBC->SetOpener(parentBC);
} }
} }
RefPtr<nsDocShell> targetDocShell(nsDocShell::Cast(targetBC->GetDocShell())); RefPtr<nsDocShell> newDocShell(nsDocShell::Cast(newBC->GetDocShell()));
// As required by spec, new windows always start out same-process, even if the // As required by spec, new windows always start out same-process, even if the
// URL being loaded will eventually load in a new process. // URL being loaded will eventually load in a new process.
MOZ_DIAGNOSTIC_ASSERT(!windowIsNew || targetDocShell); MOZ_DIAGNOSTIC_ASSERT(!windowIsNew || newDocShell);
// New top-level windows are only opened in the parent process and are, by // New top-level windows are only opened in the parent process and are, by
// definition, always in-process. // definition, always in-process.
MOZ_DIAGNOSTIC_ASSERT(!isNewToplevelWindow || targetDocShell); MOZ_DIAGNOSTIC_ASSERT(!isNewToplevelWindow || newDocShell);
// Copy sandbox flags to the new window if activeDocsSandboxFlags says to do // Copy sandbox flags to the new window if activeDocsSandboxFlags says to do
// so. Note that it's only nonzero if the window is new, so clobbering // so. Note that it's only nonzero if the window is new, so clobbering
@ -1102,46 +1060,45 @@ nsresult nsWindowWatcher::OpenWindowInternal(
if (activeDocsSandboxFlags & if (activeDocsSandboxFlags &
SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS) { SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS) {
MOZ_ASSERT(windowIsNew, "Should only get here for new windows"); MOZ_ASSERT(windowIsNew, "Should only get here for new windows");
MOZ_ALWAYS_SUCCEEDS(targetBC->SetSandboxFlags(activeDocsSandboxFlags)); MOZ_ALWAYS_SUCCEEDS(newBC->SetSandboxFlags(activeDocsSandboxFlags));
MOZ_ALWAYS_SUCCEEDS( MOZ_ALWAYS_SUCCEEDS(
targetBC->SetInitialSandboxFlags(targetBC->GetSandboxFlags())); newBC->SetInitialSandboxFlags(newBC->GetSandboxFlags()));
} }
RefPtr<nsGlobalWindowOuter> targetOuterWin( RefPtr<nsGlobalWindowOuter> win(
nsGlobalWindowOuter::Cast(targetBC->GetDOMWindow())); nsGlobalWindowOuter::Cast(newBC->GetDOMWindow()));
#ifdef DEBUG #ifdef DEBUG
if (targetOuterWin && windowIsNew) { if (win && windowIsNew) {
// Assert that we're not loading things right now. If we are, when // Assert that we're not loading things right now. If we are, when
// that load completes it will clobber whatever principals we set up // that load completes it will clobber whatever principals we set up
// on this new window! // on this new window!
nsCOMPtr<nsIChannel> chan; nsCOMPtr<nsIChannel> chan;
targetDocShell->GetDocumentChannel(getter_AddRefs(chan)); newDocShell->GetDocumentChannel(getter_AddRefs(chan));
MOZ_ASSERT(!chan, "Why is there a document channel?"); MOZ_ASSERT(!chan, "Why is there a document channel?");
if (RefPtr<Document> doc = targetOuterWin->GetExtantDoc()) { if (RefPtr<Document> doc = win->GetExtantDoc()) {
MOZ_ASSERT(doc->IsInitialDocument(), MOZ_ASSERT(doc->IsInitialDocument(),
"New window's document should be an initial document"); "New window's document should be an initial document");
} }
} }
#endif #endif
MOZ_ASSERT(targetOuterWin || !windowIsNew, MOZ_ASSERT(win || !windowIsNew, "New windows are always created in-process");
"New windows are always created in-process");
*aResult = do_AddRef(targetBC).take(); *aResult = do_AddRef(newBC).take();
if (isNewToplevelWindow) { if (isNewToplevelWindow) {
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner; nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
targetDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner)); newDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner));
MaybeDisablePersistence(sizeSpec, newTreeOwner); MaybeDisablePersistence(sizeSpec, newTreeOwner);
} }
if (aDialog && aArgv) { if (aDialog && aArgv) {
MOZ_ASSERT(targetOuterWin); MOZ_ASSERT(win);
NS_ENSURE_TRUE(targetOuterWin, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED);
// Set the args on the new window. // Set the args on the new window.
MOZ_TRY(targetOuterWin->SetArguments(aArgv)); MOZ_TRY(win->SetArguments(aArgv));
} }
/* allow a window that we found by name to keep its name (important for cases /* allow a window that we found by name to keep its name (important for cases
@ -1149,40 +1106,52 @@ nsresult nsWindowWatcher::OpenWindowInternal(
is not a window name. */ is not a window name. */
if (windowNeedsName) { if (windowNeedsName) {
if (nameSpecified && !name.LowerCaseEqualsLiteral("_blank")) { if (nameSpecified && !name.LowerCaseEqualsLiteral("_blank")) {
MOZ_ALWAYS_SUCCEEDS(targetBC->SetName(name)); MOZ_ALWAYS_SUCCEEDS(newBC->SetName(name));
} else { } else {
MOZ_ALWAYS_SUCCEEDS(targetBC->SetName(u""_ns)); MOZ_ALWAYS_SUCCEEDS(newBC->SetName(u""_ns));
} }
} }
// Now we have to set the right opener principal on the new window. Note // Now we have to set the right opener principal on the new window. Note
// that we have to do this _before_ starting any URI loads, thanks to the // that we have to do this _before_ starting any URI loads, thanks to the
// sync nature of javascript: loads. // sync nature of javascript: loads.
//
// Note: The check for the current JSContext isn't necessarily sensical.
// It's just designed to preserve old semantics during a mass-conversion
// patch.
// Bug 1498605 verify usages of systemPrincipal here
JSContext* cx = nsContentUtils::GetCurrentJSContext();
nsCOMPtr<nsIPrincipal> subjectPrincipal =
cx ? nsContentUtils::SubjectPrincipal()
: nsContentUtils::GetSystemPrincipal();
if (windowIsNew) { if (windowIsNew) {
MOZ_DIAGNOSTIC_ASSERT( if (subjectPrincipal &&
!targetBC->IsContent() || !nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal) &&
newWindowPrincipal->OriginAttributesRef().EqualsIgnoringFPD( newBC->IsContent()) {
targetBC->OriginAttributesRef())); MOZ_DIAGNOSTIC_ASSERT(
subjectPrincipal->OriginAttributesRef().EqualsIgnoringFPD(
newBC->OriginAttributesRef()));
}
bool autoPrivateBrowsing = bool autoPrivateBrowsing =
Preferences::GetBool("browser.privatebrowsing.autostart"); Preferences::GetBool("browser.privatebrowsing.autostart");
if (!autoPrivateBrowsing && if (!autoPrivateBrowsing &&
(chromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW)) { (chromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW)) {
if (targetBC->IsChrome()) { if (newBC->IsChrome()) {
targetBC->SetUsePrivateBrowsing(false); newBC->SetUsePrivateBrowsing(false);
} }
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
!targetBC->UsePrivateBrowsing(), !newBC->UsePrivateBrowsing(),
"CHROME_NON_PRIVATE_WINDOW passed, but got private window"); "CHROME_NON_PRIVATE_WINDOW passed, but got private window");
} else if (autoPrivateBrowsing || } else if (autoPrivateBrowsing ||
(chromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW)) { (chromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW)) {
if (targetBC->IsChrome()) { if (newBC->IsChrome()) {
targetBC->SetUsePrivateBrowsing(true); newBC->SetUsePrivateBrowsing(true);
} }
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
targetBC->UsePrivateBrowsing(), newBC->UsePrivateBrowsing(),
"CHROME_PRIVATE_WINDOW passed, but got non-private window"); "CHROME_PRIVATE_WINDOW passed, but got non-private window");
} }
@ -1191,47 +1160,26 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// the JS stack, just use the principal of our parent window. In those // the JS stack, just use the principal of our parent window. In those
// cases we do _not_ set the parent window principal as the owner of the // cases we do _not_ set the parent window principal as the owner of the
// load--since we really don't know who the owner is, just leave it null. // load--since we really don't know who the owner is, just leave it null.
NS_ASSERTION(targetOuterWin == targetDocShell->GetWindow(), NS_ASSERTION(win == newDocShell->GetWindow(), "Different windows??");
"Different windows??");
// Initialize the principal of the initial about:blank document. For // The principal of the initial about:blank document gets set up in
// toplevel windows, this call may have already happened when the window was // nsWindowWatcher::AddWindow. Make sure to call it. In the common case
// created, but SetInitialPrincipal is safe to call multiple times. // this call already happened when the window was created, but
if (targetOuterWin) { // SetInitialPrincipalToSubject is safe to call multiple times.
if (win) {
MOZ_ASSERT(windowIsNew); MOZ_ASSERT(windowIsNew);
MOZ_ASSERT(!targetOuterWin->GetSameProcessOpener() || MOZ_ASSERT(!win->GetSameProcessOpener() ||
targetOuterWin->GetSameProcessOpener() == aParent); win->GetSameProcessOpener() == aParent);
targetOuterWin->SetInitialPrincipal(newWindowPrincipal, win->SetInitialPrincipalToSubject(cspToInheritForAboutBlank,
cspToInheritForAboutBlank, coepToInheritForAboutBlank);
coepToInheritForAboutBlank);
if (aIsPopupSpam) { if (aIsPopupSpam) {
MOZ_ASSERT(!targetBC->GetIsPopupSpam(), MOZ_ASSERT(!newBC->GetIsPopupSpam(),
"Who marked it as popup spam already???"); "Who marked it as popup spam already???");
// Make sure we don't mess up our counter even if the above assert // Make sure we don't mess up our counter even if the above assert
// fails. // fails.
if (!targetBC->GetIsPopupSpam()) { if (!newBC->GetIsPopupSpam()) {
MOZ_ALWAYS_SUCCEEDS(targetBC->SetIsPopupSpam(true)); MOZ_ALWAYS_SUCCEEDS(newBC->SetIsPopupSpam(true));
}
}
}
// Copy the current session storage for the current domain. Don't perform
// the copy if we're forcing noopener, however.
if (!aForceNoOpener && subjectPrincipal && parentDocShell &&
targetDocShell) {
const RefPtr<SessionStorageManager> parentStorageManager =
parentDocShell->GetBrowsingContext()->GetSessionStorageManager();
const RefPtr<SessionStorageManager> newStorageManager =
targetDocShell->GetBrowsingContext()->GetSessionStorageManager();
if (parentStorageManager && newStorageManager) {
RefPtr<Storage> storage;
parentStorageManager->GetStorage(
parentInnerWin, subjectPrincipal, subjectPrincipal,
targetBC->UsePrivateBrowsing(), getter_AddRefs(storage));
if (storage) {
newStorageManager->CloneStorage(storage);
} }
} }
} }
@ -1240,12 +1188,15 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// We rely on CalculateChromeFlags to decide whether remote (out-of-process) // We rely on CalculateChromeFlags to decide whether remote (out-of-process)
// tabs should be used. // tabs should be used.
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
targetBC->UseRemoteTabs() == newBC->UseRemoteTabs() ==
!!(chromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW)); !!(chromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
targetBC->UseRemoteSubframes() == newBC->UseRemoteSubframes() ==
!!(chromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW)); !!(chromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW));
nsCOMPtr<nsPIDOMWindowInner> pInnerWin =
parentWindow ? parentWindow->GetCurrentInnerWindow() : nullptr;
;
RefPtr<nsDocShellLoadState> loadState = aLoadState; RefPtr<nsDocShellLoadState> loadState = aLoadState;
if (uriToLoad && loadState) { if (uriToLoad && loadState) {
// If a URI was passed to this function, open that, not what was passed in // If a URI was passed to this function, open that, not what was passed in
@ -1253,7 +1204,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
loadState->SetURI(uriToLoad); loadState->SetURI(uriToLoad);
} else if (uriToLoad && aNavigate && !loadState) { } else if (uriToLoad && aNavigate && !loadState) {
RefPtr<WindowContext> context = RefPtr<WindowContext> context =
parentInnerWin ? parentInnerWin->GetWindowContext() : nullptr; pInnerWin ? pInnerWin->GetWindowContext() : nullptr;
loadState = new nsDocShellLoadState(uriToLoad); loadState = new nsDocShellLoadState(uriToLoad);
loadState->SetSourceBrowsingContext(parentBC); loadState->SetSourceBrowsingContext(parentBC);
@ -1280,8 +1231,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
screw up focus in the hidden window; see bug 36016. screw up focus in the hidden window; see bug 36016.
*/ */
RefPtr<Document> doc = GetEntryDocument(); RefPtr<Document> doc = GetEntryDocument();
if (!doc) { if (!doc && parentWindow) {
doc = parentDoc; doc = parentWindow->GetExtantDoc();
} }
if (doc) { if (doc) {
auto referrerInfo = MakeRefPtr<ReferrerInfo>(*doc); auto referrerInfo = MakeRefPtr<ReferrerInfo>(*doc);
@ -1304,14 +1255,14 @@ nsresult nsWindowWatcher::OpenWindowInternal(
nsCOMPtr<nsIObserverService> obsSvc = nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService(); mozilla::services::GetObserverService();
if (obsSvc) { if (obsSvc) {
obsSvc->NotifyObservers(ToSupports(targetOuterWin), obsSvc->NotifyObservers(ToSupports(win), "toplevel-window-ready",
"toplevel-window-ready", nullptr); nullptr);
} }
} }
// Before loading the URI we want to be 100% sure that we use the correct // Before loading the URI we want to be 100% sure that we use the correct
// userContextId. // userContextId.
MOZ_ASSERT_IF(targetDocShell, CheckUserContextCompatibility(targetDocShell)); MOZ_ASSERT_IF(newDocShell, CheckUserContextCompatibility(newDocShell));
// If this tab or window has been opened by a window.open call, we have to // If this tab or window has been opened by a window.open call, we have to
// provide all the data needed to send a // provide all the data needed to send a
@ -1331,7 +1282,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
props->SetPropertyAsInterface(u"sourceTabDocShell"_ns, parentDocShell); props->SetPropertyAsInterface(u"sourceTabDocShell"_ns, parentDocShell);
props->SetPropertyAsInterface(u"createdTabDocShell"_ns, props->SetPropertyAsInterface(u"createdTabDocShell"_ns,
ToSupports(targetDocShell)); ToSupports(newDocShell));
obsSvc->NotifyObservers(static_cast<nsIPropertyBag2*>(props), obsSvc->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
"webNavigation-createdNavigationTarget-from-js", "webNavigation-createdNavigationTarget-from-js",
@ -1340,38 +1291,49 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
if (uriToLoad && aNavigate) { if (uriToLoad && aNavigate) {
uint32_t loadFlags = nsIWebNavigation::LOAD_FLAGS_NONE; // XXXBFCache Per spec this should effectively use
if (windowIsNew) { // LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL when noopener is passed to
loadFlags |= nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD; // window.open(). Bug 1694993.
loadState->SetLoadFlags(
// Per spec, the explicit navigation to about:blank after the initial windowIsNew
// about:blank document in a new window does not occur, so there is no ? static_cast<uint32_t>(nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD)
// opportunity for it to inherit the source document's principal. This : static_cast<uint32_t>(nsIWebNavigation::LOAD_FLAGS_NONE));
// doesn't perfectly model this, as a noopener creation of `about:blank`
// will replace the global due to a principal mismatch, but it should be
// unobservable (bug 1694993).
if (aForceNoOpener) {
loadFlags |= nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
}
}
loadState->SetLoadFlags(loadFlags);
loadState->SetFirstParty(true); loadState->SetFirstParty(true);
// Should this pay attention to errors returned by LoadURI? // Should this pay attention to errors returned by LoadURI?
targetBC->LoadURI(loadState); newBC->LoadURI(loadState);
}
// Copy the current session storage for the current domain. Don't perform the
// copy if we're forcing noopener, however.
if (!aForceNoOpener && subjectPrincipal && parentDocShell && newDocShell) {
const RefPtr<SessionStorageManager> parentStorageManager =
parentDocShell->GetBrowsingContext()->GetSessionStorageManager();
const RefPtr<SessionStorageManager> newStorageManager =
newDocShell->GetBrowsingContext()->GetSessionStorageManager();
if (parentStorageManager && newStorageManager) {
RefPtr<Storage> storage;
parentStorageManager->GetStorage(
pInnerWin, subjectPrincipal, subjectPrincipal,
newBC->UsePrivateBrowsing(), getter_AddRefs(storage));
if (storage) {
newStorageManager->CloneStorage(storage);
}
}
} }
if (isNewToplevelWindow) { if (isNewToplevelWindow) {
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner; nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
targetDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner)); newDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner));
SizeOpenedWindow(newTreeOwner, aParent, isCallerChrome, sizeSpec); SizeOpenedWindow(newTreeOwner, aParent, isCallerChrome, sizeSpec);
} }
if (windowIsModal) { if (windowIsModal) {
NS_ENSURE_TRUE(targetDocShell, NS_ERROR_NOT_IMPLEMENTED); NS_ENSURE_TRUE(newDocShell, NS_ERROR_NOT_IMPLEMENTED);
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner; nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
targetDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner)); newDocShell->GetTreeOwner(getter_AddRefs(newTreeOwner));
nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner)); nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
// Throw an exception here if no web browser chrome is available, // Throw an exception here if no web browser chrome is available,
@ -1385,7 +1347,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// Make sure we maintain the state on an outer window, because // Make sure we maintain the state on an outer window, because
// that's where it lives; inner windows assert if you try to // that's where it lives; inner windows assert if you try to
// maintain the state on them. // maintain the state on them.
nsAutoWindowStateHelper windowStateHelper(parentOuterWin); nsAutoWindowStateHelper windowStateHelper(parentWindow);
if (!windowStateHelper.DefaultEnabled()) { if (!windowStateHelper.DefaultEnabled()) {
// Default to cancel not opening the modal window. // Default to cancel not opening the modal window.
@ -1417,8 +1379,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
// If a website opens a popup exit DOM fullscreen // If a website opens a popup exit DOM fullscreen
if (StaticPrefs::full_screen_api_exit_on_windowOpen() && aCalledFromJS && if (StaticPrefs::full_screen_api_exit_on_windowOpen() && aCalledFromJS &&
!hasChromeParent && !isCallerChrome && parentOuterWin) { !hasChromeParent && !isCallerChrome && parentWindow) {
Document::AsyncExitFullscreen(parentOuterWin->GetDoc()); Document::AsyncExitFullscreen(parentWindow->GetDoc());
} }
if (aForceNoOpener && windowIsNew) { if (aForceNoOpener && windowIsNew) {

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

@ -746,27 +746,24 @@ nsresult nsAppShellService::JustCreateTopWindow(
nsIWebBrowserChrome::CHROME_FISSION_WINDOW); nsIWebBrowserChrome::CHROME_FISSION_WINDOW);
// Eagerly create an about:blank content viewer with the right principal // Eagerly create an about:blank content viewer with the right principal
// here, rather than letting it happen in the upcoming call to // here, rather than letting it happening in the upcoming call to
// SetInitialPrincipal. This avoids creating the about:blank document and // SetInitialPrincipalToSubject. This avoids creating the about:blank
// then blowing it away with a second one, which can cause problems for the // document and then blowing it away with a second one, which can cause
// top-level chrome window case. See bug 789773. // problems for the top-level chrome window case. See bug 789773. Note that
// Toplevel chrome windows always have a system principal, so ensure the // we don't accept expanded principals here, similar to
// initial window is created with that principal. // SetInitialPrincipalToSubject.
// We need to do this even when creating a chrome window to load a content
// window, see bug 799348 comment 13 for details about what previously
// happened here due to it using the subject principal.
if (nsContentUtils::IsInitialized()) { // Sometimes this happens really if (nsContentUtils::IsInitialized()) { // Sometimes this happens really
// early. See bug 793370. // early. See bug 793370.
MOZ_DIAGNOSTIC_ASSERT( nsCOMPtr<nsIPrincipal> principal =
nsContentUtils::LegacyIsCallerChromeOrNativeCode(), nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
"Previously, this method would use the subject principal rather than " if (nsContentUtils::IsExpandedPrincipal(principal)) {
"hardcoding the system principal"); principal = nullptr;
// Use the system principal as the storage principal too until the new }
// window finishes navigating and gets a real storage principal. // Use the subject (or system) principal as the storage principal too
// until the new window finishes navigating and gets a real storage
// principal.
rv = docShell->CreateAboutBlankContentViewer( rv = docShell->CreateAboutBlankContentViewer(
nsContentUtils::GetSystemPrincipal(), principal, principal, /* aCsp = */ nullptr, /* aBaseURI = */ nullptr,
nsContentUtils::GetSystemPrincipal(),
/* aCsp = */ nullptr, /* aBaseURI = */ nullptr,
/* aIsInitialDocument = */ true); /* aIsInitialDocument = */ true);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
RefPtr<Document> doc = docShell->GetDocument(); RefPtr<Document> doc = docShell->GetDocument();
@ -850,18 +847,7 @@ nsAppShellService::RegisterTopLevelWindow(nsIAppWindow* aWindow) {
nsCOMPtr<nsPIDOMWindowOuter> domWindow(docShell->GetWindow()); nsCOMPtr<nsPIDOMWindowOuter> domWindow(docShell->GetWindow());
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
domWindow->SetInitialPrincipalToSubject(nullptr, Nothing());
// Toplevel chrome windows always have a system principal, so ensure the
// initial window is created with that principal.
// We need to do this even when creating a chrome window to load a content
// window, see bug 799348 comment 13 for details about what previously
// happened here due to it using the subject principal.
MOZ_DIAGNOSTIC_ASSERT(
nsContentUtils::LegacyIsCallerChromeOrNativeCode(),
"Previously, this method would use the subject principal rather than "
"hardcoding the system principal");
domWindow->SetInitialPrincipal(nsContentUtils::GetSystemPrincipal(), nullptr,
Nothing());
// tell the window mediator about the new window // tell the window mediator about the new window
nsCOMPtr<nsIWindowMediator> mediator( nsCOMPtr<nsIWindowMediator> mediator(