forked from mirrors/gecko-dev
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:
parent
a2741562b7
commit
524e4f032a
19 changed files with 143 additions and 44 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<!doctype html>
|
||||
<script>
|
||||
onload = function() {
|
||||
setTimeout(() => window.location = "close_noopener_beforeunload-1.html" + location.search, 0);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in a new issue