Bug 1616353 - Part 6.1: Implement nsILoadContext on BrowsingContext, r=smaug

This also moves nsDocShell's implementation of nsILoadContext to be based on its
BrowsingContext.

This patch does not, by itself, fix all places which try to mutate
`nsILoadContext`. Those are fixed by the other parts of this patch stack.

Differential Revision: https://phabricator.services.mozilla.com/D67045

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2020-04-07 21:39:12 +00:00
Родитель 146e915363
Коммит 570fcda0e2
7 изменённых файлов: 466 добавлений и 343 удалений

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

@ -215,6 +215,11 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
BrowsingContext* inherit = aParent ? aParent : aOpener;
if (inherit) {
context->mPrivateBrowsingId = inherit->mPrivateBrowsingId;
context->mUseRemoteTabs = inherit->mUseRemoteTabs;
context->mUseRemoteSubframes = inherit->mUseRemoteSubframes;
context->mOriginAttributes = inherit->mOriginAttributes;
// CORPP 3.1.3 https://mikewest.github.io/corpp/#integration-html
context->mFields.SetWithoutSyncing<IDX_EmbedderPolicy>(
inherit->GetEmbedderPolicy());
@ -320,6 +325,13 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateFromIPC(
context->mWindowless = aInit.mWindowless;
// NOTE: Call through the `Set` methods for these values to ensure that any
// relevant process-local state is also updated.
context->SetOriginAttributes(aInit.mOriginAttributes);
context->SetRemoteTabs(aInit.mUseRemoteTabs);
context->SetRemoteSubframes(aInit.mUseRemoteSubframes);
// NOTE: Private browsing ID is set by `SetOriginAttributes`.
Register(context);
// Caller handles attaching us to the tree.
@ -340,13 +352,16 @@ BrowsingContext::BrowsingContext(BrowsingContext* aParent,
mBrowsingContextId(aBrowsingContextId),
mGroup(aGroup),
mParent(aParent),
mPrivateBrowsingId(0),
mEverAttached(false),
mIsInProcess(false),
mIsDiscarded(false),
mWindowless(false),
mDanglingRemoteOuterProxies(false),
mPendingInitialization(false),
mEmbeddedByThisProcess(false) {
mEmbeddedByThisProcess(false),
mUseRemoteTabs(false),
mUseRemoteSubframes(false) {
MOZ_RELEASE_ASSERT(!mParent || mParent->Group() == mGroup);
MOZ_RELEASE_ASSERT(mBrowsingContextId != 0);
MOZ_RELEASE_ASSERT(mGroup);
@ -442,10 +457,16 @@ void BrowsingContext::Attach(bool aFromIPC) {
MOZ_DIAGNOSTIC_ASSERT(!mEverAttached);
mEverAttached = true;
MOZ_LOG(GetLog(), LogLevel::Debug,
("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64,
XRE_IsParentProcess() ? "Parent" : "Child", Id(),
mParent ? mParent->Id() : 0));
if (MOZ_LOG_TEST(GetLog(), LogLevel::Debug)) {
nsAutoCString suffix;
mOriginAttributes.CreateSuffix(suffix);
MOZ_LOG(GetLog(), LogLevel::Debug,
("%s: Connecting 0x%08" PRIx64 " to 0x%08" PRIx64
" (private=%d, remote=%d, fission=%d, oa=%s)",
XRE_IsParentProcess() ? "Parent" : "Child", Id(),
mParent ? mParent->Id() : 0, (int)mPrivateBrowsingId,
(int)mUseRemoteTabs, (int)mUseRemoteSubframes, suffix.get()));
}
MOZ_DIAGNOSTIC_ASSERT(mGroup);
MOZ_DIAGNOSTIC_ASSERT(!mGroup->IsContextCached(this));
@ -562,6 +583,8 @@ void BrowsingContext::Detach(bool aFromIPC) {
mFields.SetWithoutSyncing<IDX_IsPopupSpam>(false);
}
AssertOriginAttributesMatchPrivateBrowsing();
if (XRE_IsParentProcess()) {
Canonical()->CanonicalDiscard();
}
@ -985,6 +1008,239 @@ bool BrowsingContext::ConsumeTransientUserGestureActivation() {
return true;
}
bool BrowsingContext::CanSetOriginAttributes() {
// A discarded BrowsingContext has already been destroyed, and cannot modify
// its OriginAttributes.
if (NS_WARN_IF(IsDiscarded())) {
return false;
}
// Before attaching is the safest time to set OriginAttributes, and the only
// allowed time for content BrowsingContexts.
if (!EverAttached()) {
return true;
}
// Attached content BrowsingContexts may have been synced to other processes.
if (NS_WARN_IF(IsContent())) {
MOZ_CRASH();
return false;
}
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
// Cannot set OriginAttributes after we've created our child BrowsingContext.
if (NS_WARN_IF(!Children().IsEmpty())) {
return false;
}
// Only allow setting OriginAttributes if we have no associated document, or
// the document is still `about:blank`.
// TODO: Bug 1273058 - should have no document when setting origin attributes.
if (WindowGlobalParent* window = Canonical()->GetCurrentWindowGlobal()) {
if (nsIURI* uri = window->GetDocumentURI()) {
MOZ_ASSERT(NS_IsAboutBlank(uri));
return NS_IsAboutBlank(uri);
}
}
return true;
}
NS_IMETHODIMP BrowsingContext::GetAssociatedWindow(
mozIDOMWindowProxy** aAssociatedWindow) {
nsCOMPtr<mozIDOMWindowProxy> win = GetDOMWindow();
win.forget(aAssociatedWindow);
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetTopWindow(mozIDOMWindowProxy** aTopWindow) {
return Top()->GetAssociatedWindow(aTopWindow);
}
NS_IMETHODIMP BrowsingContext::GetTopFrameElement(Element** aTopFrameElement) {
RefPtr<Element> topFrameElement = Top()->GetEmbedderElement();
topFrameElement.forget(aTopFrameElement);
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetNestedFrameId(uint64_t* aNestedFrameId) {
// FIXME: nestedFrameId should be removed, as it was only used by B2G.
*aNestedFrameId = 0;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetIsContent(bool* aIsContent) {
*aIsContent = IsContent();
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetUsePrivateBrowsing(
bool* aUsePrivateBrowsing) {
*aUsePrivateBrowsing = mPrivateBrowsingId > 0;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) {
if (!CanSetOriginAttributes()) {
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
if (changed) {
NS_WARNING("SetUsePrivateBrowsing when !CanSetOriginAttributes()");
}
return changed ? NS_ERROR_FAILURE : NS_OK;
}
return SetPrivateBrowsing(aUsePrivateBrowsing);
}
NS_IMETHODIMP BrowsingContext::SetPrivateBrowsing(bool aPrivateBrowsing) {
if (!CanSetOriginAttributes()) {
NS_WARNING("Attempt to set PrivateBrowsing when !CanSetOriginAttributes");
return NS_ERROR_FAILURE;
}
bool changed = aPrivateBrowsing != (mPrivateBrowsingId > 0);
if (changed) {
mPrivateBrowsingId = aPrivateBrowsing ? 1 : 0;
if (IsContent()) {
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aPrivateBrowsing);
}
}
AssertOriginAttributesMatchPrivateBrowsing();
if (changed && mDocShell) {
nsDocShell::Cast(mDocShell)->NotifyPrivateBrowsingChanged();
}
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetUseRemoteTabs(bool* aUseRemoteTabs) {
*aUseRemoteTabs = mUseRemoteTabs;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::SetRemoteTabs(bool aUseRemoteTabs) {
if (!CanSetOriginAttributes()) {
NS_WARNING("Attempt to set RemoteTabs when !CanSetOriginAttributes");
return NS_ERROR_FAILURE;
}
static bool annotated = false;
if (aUseRemoteTabs && !annotated) {
annotated = true;
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
true);
}
// Don't allow non-remote tabs with remote subframes.
if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) {
return NS_ERROR_UNEXPECTED;
}
mUseRemoteTabs = aUseRemoteTabs;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetUseRemoteSubframes(
bool* aUseRemoteSubframes) {
*aUseRemoteSubframes = mUseRemoteSubframes;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::SetRemoteSubframes(bool aUseRemoteSubframes) {
if (!CanSetOriginAttributes()) {
NS_WARNING("Attempt to set RemoteSubframes when !CanSetOriginAttributes");
return NS_ERROR_FAILURE;
}
static bool annotated = false;
if (aUseRemoteSubframes && !annotated) {
annotated = true;
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::DOMFissionEnabled, true);
}
// Don't allow non-remote tabs with remote subframes.
if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) {
return NS_ERROR_UNEXPECTED;
}
mUseRemoteSubframes = aUseRemoteSubframes;
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetUseTrackingProtection(
bool* aUseTrackingProtection) {
*aUseTrackingProtection = false;
if (GetForceEnableTrackingProtection() ||
StaticPrefs::privacy_trackingprotection_enabled() ||
(UsePrivateBrowsing() &&
StaticPrefs::privacy_trackingprotection_pbmode_enabled())) {
*aUseTrackingProtection = true;
return NS_OK;
}
if (mParent) {
return mParent->GetUseTrackingProtection(aUseTrackingProtection);
}
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::SetUseTrackingProtection(
bool aUseTrackingProtection) {
SetForceEnableTrackingProtection(aUseTrackingProtection);
return NS_OK;
}
NS_IMETHODIMP BrowsingContext::GetScriptableOriginAttributes(
JSContext* aCx, JS::MutableHandle<JS::Value> aVal) {
AssertOriginAttributesMatchPrivateBrowsing();
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMETHODIMP_(void)
BrowsingContext::GetOriginAttributes(OriginAttributes& aAttrs) {
aAttrs = mOriginAttributes;
AssertOriginAttributesMatchPrivateBrowsing();
}
nsresult BrowsingContext::SetOriginAttributes(const OriginAttributes& aAttrs) {
if (!CanSetOriginAttributes()) {
NS_WARNING("Attempt to set OriginAttributes when !CanSetOriginAttributes");
return NS_ERROR_FAILURE;
}
AssertOriginAttributesMatchPrivateBrowsing();
mOriginAttributes = aAttrs;
bool isPrivate = mOriginAttributes.mPrivateBrowsingId !=
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
// Chrome Browsing Context can not contain OriginAttributes.mPrivateBrowsingId
if (IsChrome() && isPrivate) {
mOriginAttributes.mPrivateBrowsingId =
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
}
SetPrivateBrowsing(isPrivate);
AssertOriginAttributesMatchPrivateBrowsing();
return NS_OK;
}
void BrowsingContext::AssertOriginAttributesMatchPrivateBrowsing() {
// Chrome browsing contexts must not have a private browsing OriginAttribute
// Content browsing contexts must maintain the equality:
// mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId
if (IsChrome()) {
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
} else {
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId ==
mPrivateBrowsingId);
}
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowsingContext)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
@ -1354,6 +1610,9 @@ BrowsingContext::IPCInitializer BrowsingContext::GetIPCInitializer() {
init.mParentId = mParent ? mParent->Id() : 0;
init.mCached = IsCached();
init.mWindowless = mWindowless;
init.mUseRemoteTabs = mUseRemoteTabs;
init.mUseRemoteSubframes = mUseRemoteSubframes;
init.mOriginAttributes = mOriginAttributes;
init.mFields = mFields.Fields();
return init;
}
@ -1734,6 +1993,9 @@ void IPDLParamTraits<dom::BrowsingContext::IPCInitializer>::Write(
WriteIPDLParam(aMessage, aActor, aInit.mParentId);
WriteIPDLParam(aMessage, aActor, aInit.mCached);
WriteIPDLParam(aMessage, aActor, aInit.mWindowless);
WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteTabs);
WriteIPDLParam(aMessage, aActor, aInit.mUseRemoteSubframes);
WriteIPDLParam(aMessage, aActor, aInit.mOriginAttributes);
WriteIPDLParam(aMessage, aActor, aInit.mFields);
}
@ -1745,6 +2007,10 @@ bool IPDLParamTraits<dom::BrowsingContext::IPCInitializer>::Read(
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mParentId) ||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mCached) ||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mWindowless) ||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mUseRemoteTabs) ||
!ReadIPDLParam(aMessage, aIterator, aActor,
&aInit->mUseRemoteSubframes) ||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mOriginAttributes) ||
!ReadIPDLParam(aMessage, aIterator, aActor, &aInit->mFields)) {
return false;
}

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

@ -29,6 +29,7 @@
#include "nsTArray.h"
#include "nsWrapperCache.h"
#include "nsILoadInfo.h"
#include "nsILoadContext.h"
class nsDocShellLoadState;
class nsGlobalWindowOuter;
@ -108,6 +109,7 @@ class WindowProxyHolder;
FIELD(AllowPlugins, bool) \
FIELD(AllowContentRetargeting, bool) \
FIELD(AllowContentRetargetingOnChildren, bool) \
FIELD(ForceEnableTrackingProtection, bool) \
/* These field are used to store the states of autoplay media request on \
* GeckoView only, and it would only be modified on the top level browsing \
* context. */ \
@ -136,7 +138,7 @@ class WindowProxyHolder;
// Trees of BrowsingContexts should only ever contain nodes of the
// same BrowsingContext::Type. This is enforced by asserts in the
// BrowsingContext::Create* methods.
class BrowsingContext : public nsISupports, public nsWrapperCache {
class BrowsingContext : public nsILoadContext, public nsWrapperCache {
MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD)
public:
@ -436,6 +438,7 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BrowsingContext)
NS_DECL_NSILOADCONTEXT
const Children& GetChildren() { return mChildren; }
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
@ -504,19 +507,22 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
* This object may be serialized over IPC.
*/
struct IPCInitializer {
uint64_t mId;
uint64_t mId = 0;
// IDs are used for Parent and Opener to allow for this object to be
// deserialized before other BrowsingContext in the BrowsingContextGroup
// have been initialized.
uint64_t mParentId;
uint64_t mParentId = 0;
already_AddRefed<BrowsingContext> GetParent();
already_AddRefed<BrowsingContext> GetOpener();
uint64_t GetOpenerId() const { return mozilla::Get<IDX_OpenerId>(mFields); }
bool mCached;
bool mWindowless;
bool mCached = false;
bool mWindowless = false;
bool mUseRemoteTabs = false;
bool mUseRemoteSubframes = false;
OriginAttributes mOriginAttributes;
FieldTuple mFields;
};
@ -542,6 +548,9 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
bool PendingInitialization() const { return mPendingInitialization; };
void SetPendingInitialization(bool aVal) { mPendingInitialization = aVal; };
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
nsresult SetOriginAttributes(const OriginAttributes& aAttrs);
protected:
virtual ~BrowsingContext();
BrowsingContext(BrowsingContext* aParent, BrowsingContextGroup* aGroup,
@ -554,6 +563,12 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
BrowsingContext* FindWithSpecialName(const nsAString& aName,
BrowsingContext& aRequestingContext);
// Is it early enough in the BrowsingContext's lifecycle that it is still
// OK to set OriginAttributes?
bool CanSetOriginAttributes();
void AssertOriginAttributesMatchPrivateBrowsing();
friend class ::nsOuterWindowProxy;
friend class ::nsGlobalWindowOuter;
friend class WindowContext;
@ -699,6 +714,16 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
JS::Heap<JSObject*> mWindowProxy;
LocationProxy mLocation;
// OriginAttributes for this BrowsingContext. May not be changed after this
// BrowsingContext is attached.
OriginAttributes mOriginAttributes;
// Determines if private browsing should be used. May not be changed after
// this BrowsingContext is attached. This field matches mOriginAttributes in
// content Browsing Contexts. Currently treated as a binary value: 1 - in
// private mode, 0 - not private mode.
uint32_t mPrivateBrowsingId;
// True if Attach() has been called on this BrowsingContext already.
bool mEverAttached : 1;
@ -727,6 +752,14 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
// process.
bool mEmbeddedByThisProcess : 1;
// Determines if remote (out-of-process) tabs should be used. May not be
// changed after this BrowsingContext is attached.
bool mUseRemoteTabs : 1;
// Determines if out-of-process iframes should be used. May not be changed
// after this BrowsingContext is attached.
bool mUseRemoteSubframes : 1;
// The start time of user gesture, this is only available if the browsing
// context is in process.
TimeStamp mUserGestureStart;

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

@ -360,7 +360,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
mFailedLoadType(0),
mFrameType(FRAME_TYPE_REGULAR),
mPrivateBrowsingId(0),
mDisplayMode(nsIDocShell::DISPLAY_MODE_BROWSER),
mJSRunToCompletionDepth(0),
mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE),
@ -387,13 +386,9 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mDisableMetaRefreshWhenInactive(false),
mIsAppTab(false),
mUseGlobalHistory(false),
mUseRemoteTabs(false),
mUseRemoteSubframes(false),
mUseTrackingProtection(false),
mDeviceSizeIsPageSize(false),
mWindowDraggingAllowed(false),
mInFrameSwap(false),
mInheritPrivateBrowsingId(true),
mCanExecuteScripts(false),
mFiredUnloadEvent(false),
mEODForCurrentDocument(false),
@ -412,8 +407,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mWillChangeProcess(false),
mWatchedByDevtools(false),
mIsNavigating(false) {
AssertOriginAttributesMatchPrivateBrowsing();
// If no outer window ID was provided, generate a new one.
if (aContentWindowID == 0) {
mContentWindowID = nsContentUtils::GenerateWindowId();
@ -533,6 +526,12 @@ already_AddRefed<nsDocShell> nsDocShell::Create(
return nullptr;
}
// If our BrowsingContext has private browsing enabled, update the number of
// private browsing docshells.
if (aBrowsingContext->UsePrivateBrowsing()) {
ds->NotifyPrivateBrowsingChanged();
}
// If our parent is present in this process, set up our parent now.
RefPtr<BrowsingContext> parent = aBrowsingContext->GetParent();
if (parent && parent->GetDocShell()) {
@ -801,10 +800,12 @@ nsDocShell::LoadURI(nsDocShellLoadState* aLoadState, bool aSetNavigating) {
BrowsingContext::Type bcType = mBrowsingContext->GetType();
// Set up the inheriting principal in LoadState.
nsresult rv = aLoadState->SetupInheritingPrincipal(bcType, mOriginAttributes);
nsresult rv = aLoadState->SetupInheritingPrincipal(
bcType, mBrowsingContext->OriginAttributesRef());
NS_ENSURE_SUCCESS(rv, rv);
rv = aLoadState->SetupTriggeringPrincipal(mOriginAttributes);
rv = aLoadState->SetupTriggeringPrincipal(
mBrowsingContext->OriginAttributesRef());
NS_ENSURE_SUCCESS(rv, rv);
aLoadState->CalculateLoadURIFlags();
@ -1523,66 +1524,40 @@ nsDocShell::SetAllowJavascript(bool aAllowJavascript) {
NS_IMETHODIMP
nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
AssertOriginAttributesMatchPrivateBrowsing();
*aUsePrivateBrowsing = mPrivateBrowsingId > 0;
return NS_OK;
return mBrowsingContext->GetUsePrivateBrowsing(aUsePrivateBrowsing);
}
void nsDocShell::NotifyPrivateBrowsingChanged() {
MOZ_ASSERT(!mIsBeingDestroyed);
if (mAffectPrivateSessionLifetime) {
if (UsePrivateBrowsing()) {
IncreasePrivateDocShellCount();
} else {
DecreasePrivateDocShellCount();
}
}
nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
while (iter.HasMore()) {
nsWeakPtr ref = iter.GetNext();
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
if (!obs) {
mPrivacyObservers.RemoveElement(ref);
} else {
obs->PrivateModeChanged(UsePrivateBrowsing());
}
}
}
NS_IMETHODIMP
nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) {
if (!CanSetOriginAttributes()) {
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
return changed ? NS_ERROR_FAILURE : NS_OK;
}
return SetPrivateBrowsing(aUsePrivateBrowsing);
return mBrowsingContext->SetUsePrivateBrowsing(aUsePrivateBrowsing);
}
NS_IMETHODIMP
nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing) {
MOZ_ASSERT(!mIsBeingDestroyed);
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
if (changed) {
mPrivateBrowsingId = aUsePrivateBrowsing ? 1 : 0;
if (mItemType != typeChrome) {
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aUsePrivateBrowsing);
}
if (mAffectPrivateSessionLifetime) {
if (aUsePrivateBrowsing) {
IncreasePrivateDocShellCount();
} else {
DecreasePrivateDocShellCount();
}
}
}
nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList);
while (iter.HasMore()) {
nsCOMPtr<nsILoadContext> shell = do_QueryObject(iter.GetNext());
if (shell) {
shell->SetPrivateBrowsing(aUsePrivateBrowsing);
}
}
if (changed) {
nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers);
while (iter.HasMore()) {
nsWeakPtr ref = iter.GetNext();
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref);
if (!obs) {
mPrivacyObservers.RemoveElement(ref);
} else {
obs->PrivateModeChanged(aUsePrivateBrowsing);
}
}
}
AssertOriginAttributesMatchPrivateBrowsing();
return NS_OK;
return mBrowsingContext->SetPrivateBrowsing(aUsePrivateBrowsing);
}
NS_IMETHODIMP
@ -1596,52 +1571,23 @@ nsDocShell::GetHasLoadedNonBlankURI(bool* aResult) {
NS_IMETHODIMP
nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) {
NS_ENSURE_ARG_POINTER(aUseRemoteTabs);
*aUseRemoteTabs = mUseRemoteTabs;
return NS_OK;
return mBrowsingContext->GetUseRemoteTabs(aUseRemoteTabs);
}
NS_IMETHODIMP
nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) {
if (aUseRemoteTabs) {
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
true);
}
// Don't allow non-remote tabs with remote subframes.
if (NS_WARN_IF(!aUseRemoteTabs && mUseRemoteSubframes)) {
return NS_ERROR_UNEXPECTED;
}
mUseRemoteTabs = aUseRemoteTabs;
return NS_OK;
return mBrowsingContext->SetRemoteTabs(aUseRemoteTabs);
}
NS_IMETHODIMP
nsDocShell::GetUseRemoteSubframes(bool* aUseRemoteSubframes) {
NS_ENSURE_ARG_POINTER(aUseRemoteSubframes);
*aUseRemoteSubframes = mUseRemoteSubframes;
return NS_OK;
return mBrowsingContext->GetUseRemoteSubframes(aUseRemoteSubframes);
}
NS_IMETHODIMP
nsDocShell::SetRemoteSubframes(bool aUseRemoteSubframes) {
static bool annotated = false;
if (aUseRemoteSubframes && !annotated) {
annotated = true;
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::DOMFissionEnabled, true);
}
// Don't allow non-remote tabs with remote subframes.
if (NS_WARN_IF(aUseRemoteSubframes && !mUseRemoteTabs)) {
return NS_ERROR_UNEXPECTED;
}
mUseRemoteSubframes = aUseRemoteSubframes;
return NS_OK;
return mBrowsingContext->SetRemoteSubframes(aUseRemoteSubframes);
}
NS_IMETHODIMP
@ -1650,7 +1596,6 @@ nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime) {
bool change = aAffectLifetime != mAffectPrivateSessionLifetime;
if (change && UsePrivateBrowsing()) {
AssertOriginAttributesMatchPrivateBrowsing();
if (aAffectLifetime) {
IncreasePrivateDocShellCount();
} else {
@ -1839,18 +1784,6 @@ nsDocShell::SetAllowContentRetargetingOnChildren(
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetInheritPrivateBrowsingId(bool* aInheritPrivateBrowsingId) {
*aInheritPrivateBrowsingId = mInheritPrivateBrowsingId;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetInheritPrivateBrowsingId(bool aInheritPrivateBrowsingId) {
mInheritPrivateBrowsingId = aInheritPrivateBrowsingId;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) {
NS_ENSURE_ARG_POINTER(aFullscreenAllowed);
@ -2629,9 +2562,6 @@ void nsDocShell::RecomputeCanExecuteScripts() {
nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
bool wasFrame = IsFrame();
#ifdef DEBUG
bool wasPrivate = UsePrivateBrowsing();
#endif
nsresult rv = nsDocLoader::SetDocLoaderParent(aParent);
NS_ENSURE_SUCCESS(rv, rv);
@ -2678,10 +2608,8 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
value = false;
}
SetAllowDNSPrefetch(mAllowDNSPrefetch && value);
if (mInheritPrivateBrowsingId) {
value = parentAsDocShell->GetAffectPrivateSessionLifetime();
SetAffectPrivateSessionLifetime(value);
}
SetAffectPrivateSessionLifetime(
parentAsDocShell->GetAffectPrivateSessionLifetime());
uint32_t flags;
if (NS_SUCCEEDED(parentAsDocShell->GetDefaultLoadFlags(&flags))) {
SetDefaultLoadFlags(flags);
@ -2694,12 +2622,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
// like this that might be embedded within it.
}
nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));
if (parentAsLoadContext && mInheritPrivateBrowsingId &&
NS_SUCCEEDED(parentAsLoadContext->GetUsePrivateBrowsing(&value))) {
SetPrivateBrowsing(value);
}
nsCOMPtr<nsIURIContentListener> parentURIListener(do_GetInterface(parent));
if (parentURIListener) {
mContentListener->SetParentContentListener(parentURIListener);
@ -2713,9 +2635,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
MaybeClearStorageAccessFlag();
}
NS_ASSERTION(mInheritPrivateBrowsingId || wasPrivate == UsePrivateBrowsing(),
"Private browsing state changed while inheritance was disabled");
return NS_OK;
}
@ -2829,18 +2748,6 @@ nsDocShell::GetSameTypeRootTreeItemIgnoreBrowserBoundaries(
return NS_OK;
}
void nsDocShell::AssertOriginAttributesMatchPrivateBrowsing() {
// Chrome docshells must not have a private browsing OriginAttribute
// Content docshells must maintain the equality:
// mOriginAttributes.mPrivateBrowsingId == mPrivateBrowsingId
if (mItemType == typeChrome) {
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0);
} else {
MOZ_DIAGNOSTIC_ASSERT(mOriginAttributes.mPrivateBrowsingId ==
mPrivateBrowsingId);
}
}
bool nsDocShell::IsSandboxedFrom(BrowsingContext* aTargetBC) {
// If no target then not sandboxed.
if (!aTargetBC) {
@ -3059,9 +2966,6 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild) {
childDocShell->SetUseGlobalHistory(true);
}
Cast(childDocShell)->SetRemoteTabs(mUseRemoteTabs);
Cast(childDocShell)->SetRemoteSubframes(mUseRemoteSubframes);
if (aChild->ItemType() != mItemType) {
return NS_OK;
}
@ -3678,19 +3582,20 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
mOriginAttributes, nullptr, nullptr, &isStsHost);
GetOriginAttributes(), nullptr, nullptr,
&isStsHost);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags,
mOriginAttributes, nullptr, nullptr,
GetOriginAttributes(), nullptr, nullptr,
&isPinnedHost);
NS_ENSURE_SUCCESS(rv, rv);
} else {
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
mOriginAttributes, &isStsHost);
GetOriginAttributes(), &isStsHost);
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI, flags,
mOriginAttributes, &isPinnedHost);
GetOriginAttributes(), &isPinnedHost);
}
if (Preferences::GetBool("browser.xul.error_pages.expert_bad_cert",
@ -4449,8 +4354,6 @@ nsDocShell::Destroy() {
NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,
"Unexpected item type in docshell");
AssertOriginAttributesMatchPrivateBrowsing();
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
if (serv) {
const char* msg = mItemType == typeContent
@ -4558,12 +4461,8 @@ nsDocShell::Destroy() {
// to break the cycle between us and the timers.
CancelRefreshURITimers();
if (UsePrivateBrowsing()) {
mPrivateBrowsingId = nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
mOriginAttributes.SyncAttributesWithPrivateBrowsing(false);
if (mAffectPrivateSessionLifetime) {
DecreasePrivateDocShellCount();
}
if (UsePrivateBrowsing() && mAffectPrivateSessionLifetime) {
DecreasePrivateDocShellCount();
}
return NS_OK;
@ -5100,7 +4999,6 @@ nsDocShell::SetTitle(const nsAString& aTitle) {
}
}
AssertOriginAttributesMatchPrivateBrowsing();
if (mCurrentURI && mLoadType != LOAD_ERROR_PAGE) {
UpdateGlobalHistoryTitle(mCurrentURI);
}
@ -6498,7 +6396,8 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
if (aPrincipal && !aPrincipal->IsSystemPrincipal() &&
mItemType != typeChrome) {
MOZ_ASSERT(aPrincipal->OriginAttributesRef() == mOriginAttributes);
MOZ_ASSERT(aPrincipal->OriginAttributesRef() ==
mBrowsingContext->OriginAttributesRef());
}
// Make sure timing is created. But first record whether we had it
@ -11950,63 +11849,27 @@ nsDocShell::GetAssociatedWindow(mozIDOMWindowProxy** aWindow) {
NS_IMETHODIMP
nsDocShell::GetTopWindow(mozIDOMWindowProxy** aWindow) {
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (win) {
win = win->GetInProcessTop();
}
win.forget(aWindow);
return NS_OK;
return mBrowsingContext->GetTopWindow(aWindow);
}
NS_IMETHODIMP
nsDocShell::GetTopFrameElement(Element** aElement) {
*aElement = nullptr;
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (!win) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindowOuter> top = win->GetInProcessScriptableTop();
NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
// GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
// inside <iframe mozbrowser>, we want to return the iframe, not null.
// And we want to cross the content/chrome boundary.
RefPtr<Element> elt = top->GetFrameElementInternal();
elt.forget(aElement);
return NS_OK;
return mBrowsingContext->GetTopFrameElement(aElement);
}
NS_IMETHODIMP
nsDocShell::GetNestedFrameId(uint64_t* aId) {
*aId = 0;
return NS_OK;
return mBrowsingContext->GetNestedFrameId(aId);
}
NS_IMETHODIMP
nsDocShell::GetUseTrackingProtection(bool* aUseTrackingProtection) {
*aUseTrackingProtection = false;
if (mUseTrackingProtection ||
StaticPrefs::privacy_trackingprotection_enabled() ||
(UsePrivateBrowsing() &&
StaticPrefs::privacy_trackingprotection_pbmode_enabled())) {
*aUseTrackingProtection = true;
return NS_OK;
}
RefPtr<nsDocShell> parent = GetInProcessParentDocshell();
if (parent) {
return parent->GetUseTrackingProtection(aUseTrackingProtection);
}
return NS_OK;
return mBrowsingContext->GetUseTrackingProtection(aUseTrackingProtection);
}
NS_IMETHODIMP
nsDocShell::SetUseTrackingProtection(bool aUseTrackingProtection) {
mUseTrackingProtection = aUseTrackingProtection;
return NS_OK;
return mBrowsingContext->SetUseTrackingProtection(aUseTrackingProtection);
}
NS_IMETHODIMP
@ -12642,42 +12505,14 @@ NS_IMETHODIMP nsDocShell::GetIsTopLevelContentDocShell(
NS_IMETHODIMP
nsDocShell::GetScriptableOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal) {
return GetOriginAttributes(aCx, aVal);
return mBrowsingContext->GetScriptableOriginAttributes(aCx, aVal);
}
// Implements nsIDocShell.GetOriginAttributes()
NS_IMETHODIMP
nsDocShell::GetOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aVal) {
bool ok = ToJSValue(aCx, mOriginAttributes, aVal);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}
bool nsDocShell::CanSetOriginAttributes() {
MOZ_ASSERT(mChildList.IsEmpty());
if (!mChildList.IsEmpty()) {
return false;
}
// TODO: Bug 1273058 - mContentViewer should be null when setting origin
// attributes.
if (mContentViewer) {
Document* doc = mContentViewer->GetDocument();
if (doc) {
nsIURI* uri = doc->GetDocumentURI();
if (!uri) {
return false;
}
nsCString uriSpec = uri->GetSpecOrDefault();
MOZ_ASSERT(uriSpec.EqualsLiteral("about:blank"));
if (!uriSpec.EqualsLiteral("about:blank")) {
return false;
}
}
}
return true;
return mBrowsingContext->GetScriptableOriginAttributes(aCx, aVal);
}
bool nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal,
@ -12703,26 +12538,7 @@ bool nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal,
nsresult nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs) {
MOZ_ASSERT(!mIsBeingDestroyed);
if (!CanSetOriginAttributes()) {
return NS_ERROR_FAILURE;
}
AssertOriginAttributesMatchPrivateBrowsing();
mOriginAttributes = aAttrs;
bool isPrivate = mOriginAttributes.mPrivateBrowsingId !=
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
// Chrome docshell can not contain OriginAttributes.mPrivateBrowsingId
if (mItemType == typeChrome && isPrivate) {
mOriginAttributes.mPrivateBrowsingId =
nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
}
SetPrivateBrowsing(isPrivate);
AssertOriginAttributesMatchPrivateBrowsing();
return NS_OK;
return mBrowsingContext->SetOriginAttributes(aAttrs);
}
NS_IMETHODIMP
@ -13029,7 +12845,7 @@ nsDocShell::GetAwaitingLargeAlloc(bool* aResult) {
NS_IMETHODIMP_(void)
nsDocShell::GetOriginAttributes(mozilla::OriginAttributes& aAttrs) {
aAttrs = mOriginAttributes;
mBrowsingContext->GetOriginAttributes(aAttrs);
}
HTMLEditor* nsIDocShell::GetHTMLEditor() {

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

@ -430,7 +430,7 @@ class nsDocShell final : public nsDocLoader,
}
const mozilla::OriginAttributes& GetOriginAttributes() {
return mOriginAttributes;
return mBrowsingContext->OriginAttributesRef();
}
// Determine whether this docshell corresponds to the given history entry,
@ -989,10 +989,6 @@ class nsDocShell final : public nsDocLoader,
// Convenience method for getting our parent docshell. Can return null
already_AddRefed<nsDocShell> GetInProcessParentDocshell();
// Helper assertion to enforce that mInPrivateBrowsing is in sync with
// OriginAttributes.mPrivateBrowsingId
void AssertOriginAttributesMatchPrivateBrowsing();
// Internal implementation of nsIDocShell::FirePageHideNotification.
// If aSkipCheckingDynEntries is true, it will not try to remove dynamic
// subframe entries. This is to avoid redundant RemoveDynEntries calls in all
@ -1096,6 +1092,9 @@ class nsDocShell final : public nsDocLoader,
nsresult HandleSameDocumentNavigation(nsDocShellLoadState* aLoadState,
SameDocumentNavigationState& aState);
// Called when the Private Browsing state of a nsDocShell changes.
void NotifyPrivateBrowsingChanged();
private: // data members
static nsIURIFixup* sURIFixup;
@ -1111,7 +1110,6 @@ class nsDocShell final : public nsDocLoader,
nsTObserverArray<nsWeakPtr> mPrivacyObservers;
nsTObserverArray<nsWeakPtr> mReflowObservers;
nsTObserverArray<nsWeakPtr> mScrollObservers;
mozilla::OriginAttributes mOriginAttributes;
mozilla::UniquePtr<mozilla::dom::ClientSource> mInitialClientSource;
nsCOMPtr<nsINetworkInterceptController> mInterceptController;
RefPtr<nsDOMNavigationTiming> mTiming;
@ -1242,13 +1240,6 @@ class nsDocShell final : public nsDocLoader,
// Are we a regular frame, a browser frame, or an app frame?
FrameType mFrameType;
// This represents the state of private browsing in the docshell.
// Currently treated as a binary value: 1 - in private mode, 0 - not private
// mode On content docshells mPrivateBrowsingId ==
// mOriginAttributes.mPrivateBrowsingId On chrome docshells this value will be
// set, but not have the corresponding origin attribute set.
uint32_t mPrivateBrowsingId;
// This represents the CSS display-mode we are currently using. This is mostly
// used for media queries.
DisplayMode mDisplayMode;
@ -1308,13 +1299,9 @@ class nsDocShell final : public nsDocLoader,
bool mDisableMetaRefreshWhenInactive : 1;
bool mIsAppTab : 1;
bool mUseGlobalHistory : 1;
bool mUseRemoteTabs : 1;
bool mUseRemoteSubframes : 1;
bool mUseTrackingProtection : 1;
bool mDeviceSizeIsPageSize : 1;
bool mWindowDraggingAllowed : 1;
bool mInFrameSwap : 1;
bool mInheritPrivateBrowsingId : 1;
// Because scriptability depends on the mAllowJavascript values of our
// ancestors, we cache the effective scriptability and recompute it when

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

@ -238,15 +238,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] attribute boolean allowContentRetargetingOnChildren;
/**
* True if this docShell should inherit the private browsing ID from
* its parent when reparented.
*
* NOTE: This should *not* be set false in new code, or for docShells
* inserted anywhere other than as children of panels.
*/
[infallible] attribute boolean inheritPrivateBrowsingId;
/**
* Get an array of this docShell and its children.
*

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

@ -2049,7 +2049,9 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
return NS_ERROR_UNEXPECTED;
}
mPendingBrowsingContext->EnsureAttached();
if (!EnsureBrowsingContextAttached()) {
return NS_ERROR_FAILURE;
}
// nsDocShell::Create will attach itself to the passed browsing
// context inside of nsDocShell::Create
@ -2137,37 +2139,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
NS_ENSURE_SUCCESS(rv, rv);
}
OriginAttributes attrs;
if (parentDocShell->ItemType() == docShell->ItemType()) {
attrs = parentDocShell->GetOriginAttributes();
}
// Inherit origin attributes from parent document if
// 1. It's in a content docshell.
// 2. its nodePrincipal is not a SystemPrincipal.
// 3. It's not a mozbrowser frame.
//
// For example, firstPartyDomain is computed from top-level document, it
// doesn't exist in the top-level docshell.
if (parentIsContent && !doc->NodePrincipal()->IsSystemPrincipal() &&
!OwnerIsMozBrowserFrame()) {
OriginAttributes oa = doc->NodePrincipal()->OriginAttributesRef();
// Assert on the firstPartyDomain from top-level docshell should be empty
MOZ_ASSERT_IF(mIsTopLevelContent, attrs.mFirstPartyDomain.IsEmpty());
// So far we want to make sure Inherit doesn't override any other origin
// attribute than firstPartyDomain.
MOZ_ASSERT(
attrs.mUserContextId == oa.mUserContextId,
"docshell and document should have the same userContextId attribute.");
MOZ_ASSERT(attrs.mPrivateBrowsingId == oa.mPrivateBrowsingId,
"docshell and document should have the same privateBrowsingId "
"attribute.");
attrs = oa;
}
if (OwnerIsMozBrowserFrame()) {
docShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
} else if (mPendingBrowsingContext->GetParent()) {
@ -2185,19 +2156,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
}
ApplySandboxFlags(sandboxFlags);
// Grab the userContextId from owner
nsresult rv = PopulateOriginContextIdsFromAttributes(attrs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isPrivate = false;
rv = parentDocShell->GetUsePrivateBrowsing(&isPrivate);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
if (OwnerIsMozBrowserFrame()) {
// For inproc frames, set the docshell properties.
nsAutoString name;
@ -2208,25 +2166,8 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
mOwnerContent->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozallowfullscreen));
bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozprivatebrowsing);
if (isPrivate) {
if (docShell->GetHasLoadedNonBlankURI()) {
nsContentUtils::ReportToConsoleNonLocalized(
NS_LITERAL_STRING("We should not switch to Private Browsing after "
"loading a document."),
nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("mozprivatebrowsing"), nullptr);
} else {
// This handles the case where a frames private browsing is set by
// chrome flags and not inherited by its parent.
attrs.SyncAttributesWithPrivateBrowsing(isPrivate);
}
}
}
docShell->SetOriginAttributes(attrs);
// Typically there will be a window, however for some cases such as printing
// the document is cloned with a docshell that has no window. We check
// that the window exists to ensure we don't try to gather ancestors for
@ -2537,7 +2478,9 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
return false;
}
mPendingBrowsingContext->EnsureAttached();
if (!EnsureBrowsingContextAttached()) {
return false;
}
RefPtr<ContentParent> openerContentParent;
RefPtr<nsIPrincipal> openerContentPrincipal;
@ -3576,3 +3519,88 @@ void nsFrameLoader::MaybeNotifyCrashed(BrowsingContext* aBrowsingContext,
EventDispatcher::DispatchDOMEvent(mOwnerContent, nullptr, event, nullptr,
nullptr);
}
bool nsFrameLoader::EnsureBrowsingContextAttached() {
nsresult rv;
Document* parentDoc = mOwnerContent->OwnerDoc();
MOZ_ASSERT(parentDoc);
BrowsingContext* parentContext = parentDoc->GetBrowsingContext();
MOZ_ASSERT(parentContext);
// Inherit the `use` flags from our parent BrowsingContext.
bool usePrivateBrowsing = parentContext->UsePrivateBrowsing();
bool useRemoteSubframes = parentContext->UseRemoteSubframes();
bool useRemoteTabs = parentContext->UseRemoteTabs();
// Determine the exact OriginAttributes which should be used for our
// BrowsingContext. This will be used to initialize OriginAttributes if the
// BrowsingContext has not already been created.
OriginAttributes attrs;
if (mPendingBrowsingContext->IsContent()) {
if (mPendingBrowsingContext->GetParent()) {
MOZ_ASSERT(mPendingBrowsingContext->GetParent() == parentContext);
parentContext->GetOriginAttributes(attrs);
}
// Inherit the `mFirstPartyDomain` flag from our parent document's result
// principal, if it was set.
if (parentContext->IsContent() &&
!parentDoc->NodePrincipal()->IsSystemPrincipal() &&
!OwnerIsMozBrowserFrame()) {
OriginAttributes docAttrs =
parentDoc->NodePrincipal()->OriginAttributesRef();
// We only want to inherit firstPartyDomain here, other attributes should
// be constant.
MOZ_ASSERT(attrs.EqualsIgnoringFPD(docAttrs));
attrs.mFirstPartyDomain = docAttrs.mFirstPartyDomain;
}
// Inherit the PrivateBrowsing flag across content/chrome boundaries.
attrs.SyncAttributesWithPrivateBrowsing(usePrivateBrowsing);
// A <browser> element may have overridden userContextId or
// geckoViewUserContextId.
rv = PopulateOriginContextIdsFromAttributes(attrs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
// <iframe mozbrowser> is allowed to set `mozprivatebrowsing` to
// force-enable private browsing.
if (OwnerIsMozBrowserFrame()) {
if (mOwnerContent->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozprivatebrowsing)) {
attrs.SyncAttributesWithPrivateBrowsing(true);
usePrivateBrowsing = true;
}
}
}
// If we've already been attached, return.
if (mPendingBrowsingContext->EverAttached()) {
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UsePrivateBrowsing() ==
usePrivateBrowsing);
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UseRemoteTabs() ==
useRemoteTabs);
MOZ_DIAGNOSTIC_ASSERT(mPendingBrowsingContext->UseRemoteSubframes() ==
useRemoteSubframes);
// Don't assert that our OriginAttributes match, as we could have different
// OriginAttributes in the case where we were opened using window.open.
return true;
}
// Initialize non-synced OriginAttributes and related fields.
rv = mPendingBrowsingContext->SetOriginAttributes(attrs);
NS_ENSURE_SUCCESS(rv, false);
rv = mPendingBrowsingContext->SetUsePrivateBrowsing(usePrivateBrowsing);
NS_ENSURE_SUCCESS(rv, false);
rv = mPendingBrowsingContext->SetRemoteTabs(useRemoteTabs);
NS_ENSURE_SUCCESS(rv, false);
rv = mPendingBrowsingContext->SetRemoteSubframes(useRemoteSubframes);
NS_ENSURE_SUCCESS(rv, false);
// Finish attaching.
mPendingBrowsingContext->EnsureAttached();
return true;
}

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

@ -470,6 +470,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
nsresult PopulateOriginContextIdsFromAttributes(
mozilla::OriginAttributes& aAttr);
bool EnsureBrowsingContextAttached();
RefPtr<mozilla::dom::BrowsingContext> mPendingBrowsingContext;
nsCOMPtr<nsIURI> mURIToLoad;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;