Bug 1681457 - Allow non-auxiliary BrowsingContexts created by script to close themselves, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D211792
This commit is contained in:
Nika Layzell 2024-06-05 00:06:48 +00:00
parent a2741562b7
commit 524e4f032a
19 changed files with 143 additions and 44 deletions

View file

@ -325,7 +325,7 @@ bool BrowsingContext::SameOriginWithTop() {
already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
bool aIsPopupRequested, bool aCreatedDynamically) {
CreateDetachedOptions aOptions) {
if (aParent) {
MOZ_DIAGNOSTIC_ASSERT(aParent->GetWindowContext());
MOZ_DIAGNOSTIC_ASSERT(aParent->GetBrowsingContext()->mType == aType);
@ -461,7 +461,10 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
fields.Get<IDX_AllowJavascript>() =
inherit ? inherit->GetAllowJavascript() : true;
fields.Get<IDX_IsPopupRequested>() = aIsPopupRequested;
fields.Get<IDX_IsPopupRequested>() = aOptions.isPopupRequested;
fields.Get<IDX_TopLevelCreatedByWebContent>() =
aOptions.topLevelCreatedByWebContent;
if (!parentBC) {
fields.Get<IDX_ShouldDelayMediaFromStart>() =
@ -480,7 +483,7 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
}
context->mEmbeddedByThisProcess = XRE_IsParentProcess() || aParent;
context->mCreatedDynamically = aCreatedDynamically;
context->mCreatedDynamically = aOptions.createdDynamically;
if (inherit) {
context->mPrivateBrowsingId = inherit->mPrivateBrowsingId;
context->mUseRemoteTabs = inherit->mUseRemoteTabs;
@ -507,7 +510,7 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateIndependent(
"BCs created in the content process must be related to "
"some BrowserChild");
RefPtr<BrowsingContext> bc(
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType, false));
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType, {}));
bc->mWindowless = bc->IsContent();
bc->mEmbeddedByThisProcess = true;
bc->EnsureAttached();
@ -3162,8 +3165,8 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_UseGlobalHistory>,
}
auto BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
const nsString& aUserAgent, ContentParent* aSource)
-> CanSetResult {
const nsString& aUserAgent,
ContentParent* aSource) -> CanSetResult {
if (!IsTop()) {
return CanSetResult::Deny;
}
@ -3172,8 +3175,8 @@ auto BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
}
auto BrowsingContext::CanSet(FieldIndex<IDX_PlatformOverride>,
const nsString& aPlatform, ContentParent* aSource)
-> CanSetResult {
const nsString& aPlatform,
ContentParent* aSource) -> CanSetResult {
if (!IsTop()) {
return CanSetResult::Deny;
}
@ -3207,8 +3210,8 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_EmbedderElementType>,
}
auto BrowsingContext::CanSet(FieldIndex<IDX_CurrentInnerWindowId>,
const uint64_t& aValue, ContentParent* aSource)
-> CanSetResult {
const uint64_t& aValue,
ContentParent* aSource) -> CanSetResult {
// Generally allow clearing this. We may want to be more precise about this
// check in the future.
if (aValue == 0) {
@ -3534,6 +3537,12 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_PendingInitialization>,
return IsTop() && GetPendingInitialization() && !aNewValue;
}
bool BrowsingContext::CanSet(FieldIndex<IDX_TopLevelCreatedByWebContent>,
const bool& aNewValue, ContentParent* aSource) {
// Should only be set after creation in the parent process.
return XRE_IsParentProcess() && !aSource && IsTop();
}
bool BrowsingContext::CanSet(FieldIndex<IDX_HasRestoreData>, bool aNewValue,
ContentParent* aSource) {
return IsTop();

View file

@ -135,6 +135,10 @@ struct EmbedderColorSchemes {
FIELD(EmbedderInnerWindowId, uint64_t) \
FIELD(CurrentInnerWindowId, uint64_t) \
FIELD(HadOriginalOpener, bool) \
/* Was this window created by a webpage through window.open or an anchor \
* link? In general, windows created this way may be manipulated (e.g. \
* closed, resized or moved) by content JS. */ \
FIELD(TopLevelCreatedByWebContent, bool) \
FIELD(IsPopupSpam, bool) \
/* Hold the audio muted state and should be used on top level browsing \
* contexts only */ \
@ -331,6 +335,13 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
// it.
static already_AddRefed<BrowsingContext> CreateIndependent(Type aType);
// Options which can be passed to CreateDetached.
struct CreateDetachedOptions {
bool isPopupRequested = false;
bool createdDynamically = false;
bool topLevelCreatedByWebContent = false;
};
// Create a brand-new BrowsingContext object, but does not immediately attach
// it. State such as OriginAttributes and PrivateBrowsingId may be customized
// to configure the BrowsingContext before it is attached.
@ -340,7 +351,7 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
static already_AddRefed<BrowsingContext> CreateDetached(
nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
bool aIsPopupRequested, bool aCreatedDynamically = false);
CreateDetachedOptions aOptions);
void EnsureAttached();
@ -1211,6 +1222,9 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
bool CanSet(FieldIndex<IDX_PendingInitialization>, bool aNewValue,
ContentParent* aSource);
bool CanSet(FieldIndex<IDX_TopLevelCreatedByWebContent>,
const bool& aNewValue, ContentParent* aSource);
bool CanSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aNewValue,
ContentParent* aSource);
void DidSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aOldValue);

View file

@ -317,6 +317,7 @@ void CanonicalBrowsingContext::ReplacedBy(
txn.SetBrowserId(GetBrowserId());
txn.SetIsAppTab(GetIsAppTab());
txn.SetHasSiblings(GetHasSiblings());
txn.SetTopLevelCreatedByWebContent(GetTopLevelCreatedByWebContent());
txn.SetHistoryID(GetHistoryID());
txn.SetExplicitActive(GetExplicitActive());
txn.SetEmbedderColorSchemes(GetEmbedderColorSchemes());

View file

@ -18980,7 +18980,7 @@ bool Document::IsLikelyContentInaccessibleTopLevelAboutBlank() const {
// really reliable but doesn't affect the correctness of our page probes, so
// it's not too terrible.
BrowsingContext* bc = GetBrowsingContext();
return bc && bc->IsTop() && !bc->HadOriginalOpener();
return bc && bc->IsTop() && !bc->GetTopLevelCreatedByWebContent();
}
bool Document::ShouldIncludeInTelemetry() const {

View file

@ -337,10 +337,16 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
// it will wind up attached as a child of the currently active inner window
// for the BrowsingContext, and cause no end of trouble.
if (IsTopContent(parentBC, aOwner)) {
BrowsingContext::CreateDetachedOptions options;
if (aOpenWindowInfo) {
options.topLevelCreatedByWebContent =
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent();
}
// Create toplevel context without a parent & as Type::Content.
return BrowsingContext::CreateDetached(
nullptr, opener, aSpecificGroup, frameName,
BrowsingContext::Type::Content, false);
BrowsingContext::Type::Content, options);
}
MOZ_ASSERT(!aOpenWindowInfo,
@ -348,9 +354,9 @@ static already_AddRefed<BrowsingContext> CreateBrowsingContext(
MOZ_ASSERT(!aSpecificGroup,
"Can't force BrowsingContextGroup for non-toplevel context");
return BrowsingContext::CreateDetached(parentInner, nullptr, nullptr,
frameName, parentBC->GetType(), false,
!aNetworkCreated);
return BrowsingContext::CreateDetached(
parentInner, nullptr, nullptr, frameName, parentBC->GetType(),
{.createdDynamically = !aNetworkCreated});
}
static bool InitialLoadIsRemote(Element* aOwner) {

View file

@ -4642,7 +4642,7 @@ bool nsGlobalWindowOuter::CanMoveResizeWindows(CallerType aCallerType) {
if (aCallerType != CallerType::System) {
// Don't allow scripts to move or resize windows that were not opened by a
// script.
if (!mBrowsingContext->HadOriginalOpener()) {
if (!mBrowsingContext->GetTopLevelCreatedByWebContent()) {
return false;
}
@ -6001,8 +6001,8 @@ void nsGlobalWindowOuter::CloseOuter(bool aTrustedCaller) {
NS_ENSURE_SUCCESS_VOID(rv);
if (!StringBeginsWith(url, u"about:neterror"_ns) &&
!mBrowsingContext->HadOriginalOpener() && !aTrustedCaller &&
!IsOnlyTopLevelDocumentInSHistory()) {
!mBrowsingContext->GetTopLevelCreatedByWebContent() &&
!aTrustedCaller && !IsOnlyTopLevelDocumentInSHistory()) {
bool allowClose =
mAllowScriptsToClose ||
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);

View file

@ -16,7 +16,7 @@
type: windowopen,
noopener: true,
shouldCloseWithoutHistory: true,
shouldCloseWithHistory: false
shouldCloseWithHistory: true
},
{
type: windowopen,
@ -28,7 +28,7 @@
type: link,
noopener: true,
shouldCloseWithoutHistory: true,
shouldCloseWithHistory: false
shouldCloseWithHistory: true
},
{
type: link,

View file

@ -1034,7 +1034,8 @@ nsresult ContentChild::ProvideWindowCommon(
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsSpecialName(name));
Unused << SendCreateWindowInDifferentProcess(
aTabOpener, parent, aChromeFlags, aCalledFromJS, aURI, features,
aTabOpener, parent, aChromeFlags, aCalledFromJS,
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent(), aURI, features,
aModifiers, name, triggeringPrincipal, csp, referrerInfo,
aOpenWindowInfo->GetOriginAttributes());
@ -1056,7 +1057,8 @@ nsresult ContentChild::ProvideWindowCommon(
RefPtr<BrowsingContext> browsingContext = BrowsingContext::CreateDetached(
nullptr, openerBC, nullptr, aName, BrowsingContext::Type::Content,
aIsPopupRequested);
{.isPopupRequested = aIsPopupRequested,
.topLevelCreatedByWebContent = true});
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteTabs(true));
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetRemoteSubframes(useRemoteSubframes));
MOZ_ALWAYS_SUCCEEDS(browsingContext->SetOriginAttributes(
@ -1181,9 +1183,11 @@ nsresult ContentChild::ProvideWindowCommon(
if (aForceNoOpener || !parent) {
MOZ_DIAGNOSTIC_ASSERT(!browsingContext->HadOriginalOpener());
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetTopLevelCreatedByWebContent());
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == 0);
} else {
MOZ_DIAGNOSTIC_ASSERT(browsingContext->HadOriginalOpener());
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetTopLevelCreatedByWebContent());
MOZ_DIAGNOSTIC_ASSERT(browsingContext->GetOpenerId() == parent->Id());
}
@ -1236,8 +1240,9 @@ nsresult ContentChild::ProvideWindowCommon(
SendCreateWindow(aTabOpener, parent, newChild, aChromeFlags, aCalledFromJS,
aOpenWindowInfo->GetIsForPrinting(),
aOpenWindowInfo->GetIsForWindowDotPrint(), aURI, features,
aModifiers, triggeringPrincipal, csp, referrerInfo,
aOpenWindowInfo->GetIsForWindowDotPrint(),
aOpenWindowInfo->GetIsTopLevelCreatedByWebContent(), aURI,
features, aModifiers, triggeringPrincipal, csp, referrerInfo,
aOpenWindowInfo->GetOriginAttributes(), std::move(resolve),
std::move(reject));

View file

@ -5567,8 +5567,8 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
const bool& aForPrinting, const bool& aForWindowDotPrint,
nsIURI* aURIToLoad, const nsACString& aFeatures,
const UserActivation::Modifiers& aModifiers,
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
bool* aWindowIsNew, int32_t& aOpenLocation,
@ -5592,6 +5592,7 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
openInfo->mIsForWindowDotPrint = aForWindowDotPrint;
openInfo->mNextRemoteBrowser = aNextRemoteBrowser;
openInfo->mOriginAttributes = aOriginAttributes;
openInfo->mIsTopLevelCreatedByWebContent = aIsTopLevelCreatedByWebContent;
MOZ_ASSERT_IF(aForWindowDotPrint, aForPrinting);
@ -5794,8 +5795,9 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
const bool& aCalledFromJS, const bool& aForPrinting,
const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
const bool& aForWindowDotPrint, const bool& aIsTopLevelCreatedByWebContent,
nsIURI* aURIToLoad, const nsACString& aFeatures,
const UserActivation::Modifiers& aModifiers,
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
CreateWindowResolver&& aResolve) {
@ -5880,10 +5882,10 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
aThisTab, *parent, newBCOpenerId != 0, aChromeFlags, aCalledFromJS,
aForPrinting, aForWindowDotPrint, aURIToLoad, aFeatures, aModifiers,
newTab, VoidString(), rv, newRemoteTab, &cwi.windowOpened(), openLocation,
aTriggeringPrincipal, aReferrerInfo, /* aLoadUri = */ false, aCsp,
aOriginAttributes);
aForPrinting, aForWindowDotPrint, aIsTopLevelCreatedByWebContent,
aURIToLoad, aFeatures, aModifiers, newTab, VoidString(), rv, newRemoteTab,
&cwi.windowOpened(), openLocation, aTriggeringPrincipal, aReferrerInfo,
/* aLoadUri = */ false, aCsp, aOriginAttributes);
if (!ipcResult) {
return ipcResult;
}
@ -5916,7 +5918,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
const uint32_t& aChromeFlags, const bool& aCalledFromJS, nsIURI* aURIToLoad,
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
const nsAString& aName, nsIPrincipal* aTriggeringPrincipal,
nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
@ -5962,7 +5965,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
aThisTab, *parent, /* aSetOpener = */ false, aChromeFlags, aCalledFromJS,
/* aForPrinting = */ false,
/* aForPrintPreview = */ false, aURIToLoad, aFeatures, aModifiers,
/* aForWindowDotPrint = */ false, aIsTopLevelCreatedByWebContent,
aURIToLoad, aFeatures, aModifiers,
/* aNextRemoteBrowser = */ nullptr, aName, rv, newRemoteTab, &windowIsNew,
openLocation, aTriggeringPrincipal, aReferrerInfo,
/* aLoadUri = */ true, aCsp, aOriginAttributes);

View file

@ -474,8 +474,9 @@ class ContentParent final : public PContentParent,
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
PBrowserParent* aNewTab, const uint32_t& aChromeFlags,
const bool& aCalledFromJS, const bool& aForPrinting,
const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
const bool& aForWindowDotPrint, const bool& aTopLevelCreatedByWebContent,
nsIURI* aURIToLoad, const nsACString& aFeatures,
const UserActivation::Modifiers& aModifiers,
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
nsIReferrerInfo* aReferrerInfo, const OriginAttributes& aOriginAttributes,
CreateWindowResolver&& aResolve);
@ -483,10 +484,10 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
PBrowserParent* aThisTab, const MaybeDiscarded<BrowsingContext>& aParent,
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
nsIURI* aURIToLoad, const nsACString& aFeatures,
const UserActivation::Modifiers& aModifiers, const nsAString& aName,
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
nsIReferrerInfo* aReferrerInfo,
const bool& aTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
const nsAString& aName, nsIPrincipal* aTriggeringPrincipal,
nsIContentSecurityPolicy* aCsp, nsIReferrerInfo* aReferrerInfo,
const OriginAttributes& aOriginAttributes);
static void BroadcastBlobURLRegistration(
@ -700,8 +701,8 @@ class ContentParent final : public PContentParent,
PBrowserParent* aThisTab, BrowsingContext& aParent, bool aSetOpener,
const uint32_t& aChromeFlags, const bool& aCalledFromJS,
const bool& aForPrinting, const bool& aForWindowDotPrint,
nsIURI* aURIToLoad, const nsACString& aFeatures,
const UserActivation::Modifiers& aModifiers,
const bool& aIsTopLevelCreatedByWebContent, nsIURI* aURIToLoad,
const nsACString& aFeatures, const UserActivation::Modifiers& aModifiers,
BrowserParent* aNextRemoteBrowser, const nsAString& aName,
nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
bool* aWindowIsNew, int32_t& aOpenLocation,

View file

@ -1533,6 +1533,7 @@ parent:
bool aCalledFromJS,
bool aForPrinting,
bool aForWindowDotPrint,
bool aTopLevelCreatedByContent,
nullable nsIURI aURIToLoad,
nsCString aFeatures,
Modifiers aModifiers,
@ -1547,6 +1548,7 @@ parent:
MaybeDiscardedBrowsingContext aParent,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aTopLevelCreatedByContent,
nullable nsIURI aURIToLoad,
nsCString aFeatures,
Modifiers aModifiers,

View file

@ -0,0 +1,8 @@
<!doctype html>
<script>
let chan = new BroadcastChannel("close_noopener_beforeunload" + location.search);
onload = function() { window.close(); };
onbeforeunload = function() {
chan.postMessage({ name: "beforeunload", history: history.length });
}
</script>

View file

@ -0,0 +1,6 @@
<!doctype html>
<script>
onload = function() {
setTimeout(() => window.location = "close_noopener_beforeunload-1.html" + location.search, 0);
}
</script>

View file

@ -0,0 +1,24 @@
<!doctype html>
<title>Running beforeunload handler in window.close() for noopener window</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
async_test(t => {
window.open("close_noopener_beforeunload-2.html?2", "", "noopener");
let chan = new BroadcastChannel("close_noopener_beforeunload?2");
chan.onmessage = t.step_func_done(function(event) {
assert_equals(event.data.name, "beforeunload", "correct message received");
assert_equals(event.data.history, 2, "session history has multiple entries");
});
}, "closing noopener window with 2 entries");
async_test(t => {
window.open("close_noopener_beforeunload-1.html?1", "", "noopener");
let chan = new BroadcastChannel("close_noopener_beforeunload?1");
chan.onmessage = t.step_func_done(function(event) {
assert_equals(event.data.name, "beforeunload", "correct message received");
assert_equals(event.data.history, 1, "session history has a single entry");
});
}, "closing noopener window with 1 entry");
</script>

View file

@ -60,6 +60,10 @@ interface nsIOpenWindowInfo : nsISupports {
[infallible]
readonly attribute boolean isForWindowDotPrint;
/** Whether this new window creation was prompted by web content */
[infallible]
readonly attribute boolean isTopLevelCreatedByWebContent;
/** BrowserParent instance to use in the new window */
[notxpcom, nostdcall]
BrowserParent getNextRemoteBrowser();

View file

@ -37,6 +37,12 @@ NS_IMETHODIMP nsOpenWindowInfo::GetForceNoOpener(bool* aForceNoOpener) {
return NS_OK;
}
NS_IMETHODIMP nsOpenWindowInfo::GetIsTopLevelCreatedByWebContent(
bool* aIsTopLevelCreatedByWebContent) {
*aIsTopLevelCreatedByWebContent = mIsTopLevelCreatedByWebContent;
return NS_OK;
}
NS_IMETHODIMP nsOpenWindowInfo::GetScriptableOriginAttributes(
JSContext* aCx, JS::MutableHandle<JS::Value> aAttrs) {
bool ok = ToJSValue(aCx, mOriginAttributes, aAttrs);

View file

@ -22,6 +22,7 @@ class nsOpenWindowInfo : public nsIOpenWindowInfo {
bool mIsRemote = false;
bool mIsForPrinting = false;
bool mIsForWindowDotPrint = false;
bool mIsTopLevelCreatedByWebContent = false;
RefPtr<mozilla::dom::BrowserParent> mNextRemoteBrowser;
mozilla::OriginAttributes mOriginAttributes;
RefPtr<mozilla::dom::BrowsingContext> mParent;

View file

@ -884,6 +884,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
openWindowInfo->mParent = parentBC;
openWindowInfo->mIsForPrinting = aPrintKind != PRINT_NONE;
openWindowInfo->mIsForWindowDotPrint = aPrintKind == PRINT_WINDOW_DOT_PRINT;
openWindowInfo->mIsTopLevelCreatedByWebContent =
!nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal);
// We're going to want the window to be immediately available, meaning we
// want it to match the current remoteness.
@ -1077,6 +1079,12 @@ nsresult nsWindowWatcher::OpenWindowInternal(
return rv;
}
MOZ_DIAGNOSTIC_ASSERT(
!windowIsNew || !targetBC->IsContent() ||
nsContentUtils::IsSystemOrExpandedPrincipal(subjectPrincipal) ||
targetBC->GetTopLevelCreatedByWebContent(),
"New BC not marked as created by web content, but it was");
// If our parent is sandboxed, set it as the one permitted sandboxed navigator
// on the new window we're opening.
if (activeDocsSandboxFlags && parentBC) {

View file

@ -1061,7 +1061,7 @@ nsExternalHelperAppService::LoadURI(nsIURI* aURI,
// Also allow this load if the target is a toplevel BC and contains a
// non-web-controlled about:blank document
if (bc->IsTop() && !bc->HadOriginalOpener() && wgp) {
if (bc->IsTop() && !bc->GetTopLevelCreatedByWebContent() && wgp) {
RefPtr<nsIURI> uri = wgp->GetDocumentURI();
foundAccessibleFrame =
uri && uri->GetSpecOrDefault().EqualsLiteral("about:blank");