зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1536411 - StoragePrincipal - part 1 - Implementation, r=Ehsan
Differential Revision: https://phabricator.services.mozilla.com/D24025 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
4b6aa5b40f
Коммит
5cfeeda19e
|
@ -455,6 +455,28 @@ BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain() {
|
|||
return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
||||
}
|
||||
|
||||
already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingFirstPartyDomain(
|
||||
nsIURI* aURI) {
|
||||
if (NS_WARN_IF(!IsCodebasePrincipal())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OriginAttributes attrs = OriginAttributesRef();
|
||||
// XXX this is slow. Maybe we should consider to make it faster.
|
||||
attrs.SetFirstPartyDomain(false, aURI, true /* aForced */);
|
||||
|
||||
nsAutoCString originNoSuffix;
|
||||
nsresult rv = GetOriginNoSuffix(originNoSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
nsIURI* uri = static_cast<ContentPrincipal*>(this)->mCodebase;
|
||||
RefPtr<ContentPrincipal> copy = new ContentPrincipal();
|
||||
rv = copy->Init(uri, attrs, originNoSuffix);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return copy.forget();
|
||||
}
|
||||
|
||||
extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
|
||||
if (!Is<ExpandedPrincipal>()) {
|
||||
return nullptr;
|
||||
|
|
|
@ -169,6 +169,8 @@ class BasePrincipal : public nsJSPrincipals {
|
|||
already_AddRefed<BasePrincipal>
|
||||
CloneStrippingUserContextIdAndFirstPartyDomain();
|
||||
|
||||
already_AddRefed<BasePrincipal> CloneForcingFirstPartyDomain(nsIURI* aURI);
|
||||
|
||||
// If this is an add-on content script principal, returns its AddonPolicy.
|
||||
// Otherwise returns null.
|
||||
extensions::WebExtensionPolicy* ContentScriptAddonPolicy();
|
||||
|
|
|
@ -38,11 +38,11 @@ void OriginAttributes::InitPrefs() {
|
|||
}
|
||||
|
||||
void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
nsIURI* aURI) {
|
||||
nsIURI* aURI, bool aForced) {
|
||||
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
||||
|
||||
// If the pref is off or this is not a top level load, bail out.
|
||||
if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
|
||||
// If the prefs are off or this is not a top level load, bail out.
|
||||
if ((!isFirstPartyEnabled || !aIsTopLevelDocument) && !aForced) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ class OriginAttributes : public dom::OriginAttributesDictionary {
|
|||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther) {}
|
||||
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI);
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI,
|
||||
bool aForced = false);
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
const nsACString& aDomain);
|
||||
|
||||
|
|
|
@ -197,6 +197,7 @@ interface nsIScriptSecurityManager : nsISupports
|
|||
in nsIURI aTargetURI,
|
||||
in boolean reportError,
|
||||
in boolean fromPrivateWindow);
|
||||
|
||||
/**
|
||||
* Get the principal for the given channel. This will typically be the
|
||||
* channel owner if there is one, and the codebase principal for the
|
||||
|
@ -204,6 +205,23 @@ interface nsIScriptSecurityManager : nsISupports
|
|||
*/
|
||||
nsIPrincipal getChannelResultPrincipal(in nsIChannel aChannel);
|
||||
|
||||
/**
|
||||
* Get the storage principal for the given channel. This is basically the
|
||||
* same of getChannelResultPrincipal() execept for trackers, where we
|
||||
* return a principal with a different OriginAttributes.
|
||||
*/
|
||||
nsIPrincipal getChannelResultStoragePrincipal(in nsIChannel aChannel);
|
||||
|
||||
/**
|
||||
* This method does getChannelResultPrincipal() +
|
||||
* getChannelResultStoragePrincipal().
|
||||
* This method is mainly done for Document::Reset(). There are no other
|
||||
* reasons to use this method.
|
||||
*/
|
||||
void getChannelResultPrincipals(in nsIChannel aChannel,
|
||||
out nsIPrincipal aPrincipal,
|
||||
out nsIPrincipal aStoragePrincipal);
|
||||
|
||||
/**
|
||||
* Temporary API until bug 1220687 is fixed.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "nsScriptSecurityManager.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/StoragePrincipalHelper.h"
|
||||
|
||||
#include "xpcpublic.h"
|
||||
#include "XPCWrapper.h"
|
||||
|
@ -245,6 +246,33 @@ nsresult nsScriptSecurityManager::GetChannelResultPrincipalIfNotSandboxed(
|
|||
/*aIgnoreSandboxing*/ true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetChannelResultStoragePrincipal(
|
||||
nsIChannel* aChannel, nsIPrincipal** aPrincipal) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = GetChannelResultPrincipal(aChannel, getter_AddRefs(principal),
|
||||
/*aIgnoreSandboxing*/ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return StoragePrincipalHelper::Create(aChannel, principal, aPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetChannelResultPrincipals(
|
||||
nsIChannel* aChannel, nsIPrincipal** aPrincipal,
|
||||
nsIPrincipal** aStoragePrincipal) {
|
||||
nsresult rv = GetChannelResultPrincipal(aChannel, aPrincipal,
|
||||
/*aIgnoreSandboxing*/ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return StoragePrincipalHelper::Create(aChannel, *aPrincipal,
|
||||
aStoragePrincipal);
|
||||
}
|
||||
|
||||
static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
// loading a data: URI into an iframe, or loading frame[srcdoc] need
|
||||
|
|
|
@ -1923,23 +1923,32 @@ bool Document::IsVisibleConsideringAncestors() const {
|
|||
void Document::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal;
|
||||
if (aChannel) {
|
||||
// Note: this code is duplicated in XULDocument::StartDocumentLoad and
|
||||
// nsScriptSecurityManager::GetChannelResultPrincipal.
|
||||
// nsScriptSecurityManager::GetChannelResultPrincipals.
|
||||
// Note: this should match nsDocShell::OnLoadingSite
|
||||
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
|
||||
nsIScriptSecurityManager* securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
if (securityManager) {
|
||||
securityManager->GetChannelResultPrincipal(aChannel,
|
||||
getter_AddRefs(principal));
|
||||
securityManager->GetChannelResultPrincipals(
|
||||
aChannel, getter_AddRefs(principal),
|
||||
getter_AddRefs(storagePrincipal));
|
||||
}
|
||||
}
|
||||
|
||||
principal = MaybeDowngradePrincipal(principal);
|
||||
bool equal = principal->Equals(storagePrincipal);
|
||||
|
||||
ResetToURI(uri, aLoadGroup, principal);
|
||||
principal = MaybeDowngradePrincipal(principal);
|
||||
if (equal) {
|
||||
storagePrincipal = principal;
|
||||
} else {
|
||||
storagePrincipal = MaybeDowngradePrincipal(storagePrincipal);
|
||||
}
|
||||
|
||||
ResetToURI(uri, aLoadGroup, principal, storagePrincipal);
|
||||
|
||||
// Note that, since mTiming does not change during a reset, the
|
||||
// navigationStart time remains unchanged and therefore any future new
|
||||
|
@ -2031,8 +2040,10 @@ void Document::DisconnectNodeTree() {
|
|||
}
|
||||
|
||||
void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) {
|
||||
MOZ_ASSERT(aURI, "Null URI passed to ResetToURI");
|
||||
MOZ_ASSERT(!!aPrincipal == !!aStoragePrincipal);
|
||||
|
||||
MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug,
|
||||
("DOCUMENT %p ResetToURI %s", this, aURI->GetSpecOrDefault().get()));
|
||||
|
@ -2062,7 +2073,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
|||
// This ensures that, during teardown, the document and the dying window
|
||||
// (which already nulled out its document pointer and cached the principal)
|
||||
// have matching principals.
|
||||
SetPrincipal(nullptr);
|
||||
SetPrincipals(nullptr, nullptr);
|
||||
|
||||
// Clear the original URI so SetDocumentURI sets it.
|
||||
mOriginalURI = nullptr;
|
||||
|
@ -2110,7 +2121,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
|||
|
||||
// Now get our new principal
|
||||
if (aPrincipal) {
|
||||
SetPrincipal(aPrincipal);
|
||||
SetPrincipals(aPrincipal, aStoragePrincipal);
|
||||
} else {
|
||||
nsIScriptSecurityManager* securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
@ -2130,7 +2141,7 @@ void Document::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
|||
nsresult rv = securityManager->GetLoadContextCodebasePrincipal(
|
||||
mDocumentURI, loadContext, getter_AddRefs(principal));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetPrincipal(principal);
|
||||
SetPrincipals(principal, principal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2793,7 +2804,7 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
|
|||
if (needNewNullPrincipal) {
|
||||
principal = NullPrincipal::CreateWithInheritedAttributes(principal);
|
||||
principal->SetCsp(csp);
|
||||
SetPrincipal(principal);
|
||||
SetPrincipals(principal, principal);
|
||||
}
|
||||
|
||||
// ----- Enforce frame-ancestor policy on any applied policies
|
||||
|
@ -3017,7 +3028,9 @@ void Document::RemoveFromIdTable(Element* aElement, nsAtom* aId) {
|
|||
}
|
||||
}
|
||||
|
||||
void Document::SetPrincipal(nsIPrincipal* aNewPrincipal) {
|
||||
void Document::SetPrincipals(nsIPrincipal* aNewPrincipal,
|
||||
nsIPrincipal* aNewStoragePrincipal) {
|
||||
MOZ_ASSERT(!!aNewPrincipal == !!aNewStoragePrincipal);
|
||||
if (aNewPrincipal && mAllowDNSPrefetch && sDisablePrefetchHTTPSPref) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aNewPrincipal->GetURI(getter_AddRefs(uri));
|
||||
|
@ -3027,6 +3040,7 @@ void Document::SetPrincipal(nsIPrincipal* aNewPrincipal) {
|
|||
}
|
||||
}
|
||||
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
|
||||
mIntrinsicStoragePrincipal = aNewStoragePrincipal;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Validate that the docgroup is set correctly by calling its getter and
|
||||
|
@ -8193,7 +8207,8 @@ nsresult Document::CloneDocHelper(Document* clone) const {
|
|||
}
|
||||
clone->mChannel = channel;
|
||||
if (uri) {
|
||||
clone->ResetToURI(uri, loadGroup, NodePrincipal());
|
||||
clone->ResetToURI(uri, loadGroup, NodePrincipal(),
|
||||
EffectiveStoragePrincipal());
|
||||
}
|
||||
|
||||
clone->SetContainer(mDocumentContainer);
|
||||
|
@ -8207,7 +8222,7 @@ nsresult Document::CloneDocHelper(Document* clone) const {
|
|||
// them.
|
||||
clone->SetDocumentURI(Document::GetDocumentURI());
|
||||
clone->SetChromeXHRDocURI(mChromeXHRDocURI);
|
||||
clone->SetPrincipal(NodePrincipal());
|
||||
clone->SetPrincipals(NodePrincipal(), EffectiveStoragePrincipal());
|
||||
clone->mDocumentBaseURI = mDocumentBaseURI;
|
||||
clone->SetChromeXHRDocBaseURI(mChromeXHRDocBaseURI);
|
||||
|
||||
|
@ -12829,5 +12844,23 @@ nsICookieSettings* Document::CookieSettings() {
|
|||
return mCookieSettings;
|
||||
}
|
||||
|
||||
nsIPrincipal* Document::EffectiveStoragePrincipal() const {
|
||||
if (!StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) {
|
||||
return NodePrincipal();
|
||||
}
|
||||
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForDocument(this);
|
||||
|
||||
// Let's use the storage principal only if we need to partition the cookie
|
||||
// jar. When the permission is granted, access will be different and the
|
||||
// normal principal will be used.
|
||||
if (access != nsContentUtils::StorageAccess::ePartitionedOrDeny) {
|
||||
return NodePrincipal();
|
||||
}
|
||||
|
||||
return mIntrinsicStoragePrincipal;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -523,9 +523,15 @@ class Document : public nsINode,
|
|||
return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
|
||||
}
|
||||
|
||||
nsIPrincipal* EffectiveStoragePrincipal() const;
|
||||
|
||||
// nsIScriptObjectPrincipal
|
||||
nsIPrincipal* GetPrincipal() final { return NodePrincipal(); }
|
||||
|
||||
nsIPrincipal* GetEffectiveStoragePrincipal() final {
|
||||
return EffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
// EventTarget
|
||||
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
||||
EventListenerManager* GetOrCreateListenerManager() override;
|
||||
|
@ -725,10 +731,10 @@ class Document : public nsINode,
|
|||
void SetReferrer(const nsACString& aReferrer) { mReferrer = aReferrer; }
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document. Chances are,
|
||||
* you do not want to be using this.
|
||||
* Set the principals responsible for this document. Chances are, you do not
|
||||
* want to be using this.
|
||||
*/
|
||||
void SetPrincipal(nsIPrincipal* aPrincipal);
|
||||
void SetPrincipals(nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal);
|
||||
|
||||
/**
|
||||
* Get the list of ancestor principals for a document. This is the same as
|
||||
|
@ -2086,12 +2092,13 @@ class Document : public nsINode,
|
|||
virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
|
||||
|
||||
/**
|
||||
* Reset this document to aURI, aLoadGroup, and aPrincipal. aURI must not be
|
||||
* null. If aPrincipal is null, a codebase principal based on aURI will be
|
||||
* used.
|
||||
* Reset this document to aURI, aLoadGroup, aPrincipal and aStoragePrincipal.
|
||||
* aURI must not be null. If aPrincipal is null, a codebase principal based
|
||||
* on aURI will be used.
|
||||
*/
|
||||
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal);
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal);
|
||||
|
||||
/**
|
||||
* Set the container (docshell) for this document. Virtual so that
|
||||
|
@ -4734,6 +4741,9 @@ class Document : public nsINode,
|
|||
|
||||
bool mInRDMPane;
|
||||
|
||||
// The principal to use for the storage area of this document.
|
||||
nsCOMPtr<nsIPrincipal> mIntrinsicStoragePrincipal;
|
||||
|
||||
public:
|
||||
// Needs to be public because the bindings code pokes at it.
|
||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||
|
|
|
@ -8226,7 +8226,7 @@ nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForWindow(
|
|||
|
||||
// static, public
|
||||
nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForDocument(
|
||||
Document* aDoc) {
|
||||
const Document* aDoc) {
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) {
|
||||
|
|
|
@ -2995,7 +2995,7 @@ class nsContentUtils {
|
|||
* the window's extant document has not been set yet. The code in
|
||||
* StorageAllowedForWindow(), however, will not work in these cases.
|
||||
*/
|
||||
static StorageAccess StorageAllowedForDocument(Document* aDoc);
|
||||
static StorageAccess StorageAllowedForDocument(const Document* aDoc);
|
||||
|
||||
/*
|
||||
* Checks if storage should be allowed for a new window with the given
|
||||
|
|
|
@ -1128,6 +1128,7 @@ void nsGlobalWindowInner::FreeInnerObjects() {
|
|||
if (mDoc) {
|
||||
// Remember the document's principal and URI.
|
||||
mDocumentPrincipal = mDoc->NodePrincipal();
|
||||
mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
|
||||
mDocumentURI = mDoc->GetDocumentURI();
|
||||
mDocBaseURI = mDoc->GetDocBaseURI();
|
||||
|
||||
|
@ -1357,6 +1358,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplicationCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)
|
||||
|
||||
|
@ -1460,6 +1462,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
|
||||
|
||||
|
@ -2048,6 +2051,29 @@ nsIPrincipal* nsGlobalWindowInner::GetPrincipal() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIPrincipal* nsGlobalWindowInner::GetEffectiveStoragePrincipal() {
|
||||
if (mDoc) {
|
||||
// If we have a document, get the principal from the document
|
||||
return mDoc->EffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
if (mDocumentStoragePrincipal) {
|
||||
return mDocumentStoragePrincipal;
|
||||
}
|
||||
|
||||
// If we don't have a storage principal and we don't have a document we ask
|
||||
// the parent window for the storage principal.
|
||||
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
|
||||
do_QueryInterface(GetParentInternal());
|
||||
|
||||
if (objPrincipal) {
|
||||
return objPrincipal->GetEffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindowInner::nsIDOMWindow
|
||||
//*****************************************************************************
|
||||
|
@ -2795,10 +2821,9 @@ bool nsGlobalWindowInner::MayResolve(jsid aId) {
|
|||
return WebIDLGlobalNameHash::MayResolve(aId);
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::GetOwnPropertyNames(JSContext* aCx,
|
||||
JS::MutableHandleVector<jsid> aNames,
|
||||
bool aEnumerableOnly,
|
||||
ErrorResult& aRv) {
|
||||
void nsGlobalWindowInner::GetOwnPropertyNames(
|
||||
JSContext* aCx, JS::MutableHandleVector<jsid> aNames, bool aEnumerableOnly,
|
||||
ErrorResult& aRv) {
|
||||
if (aEnumerableOnly) {
|
||||
// The names we would return from here get defined on the window via one of
|
||||
// two codepaths. The ones coming from the WebIDLGlobalNameHash will end up
|
||||
|
|
|
@ -260,6 +260,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
// nsIScriptObjectPrincipal
|
||||
virtual nsIPrincipal* GetPrincipal() override;
|
||||
|
||||
virtual nsIPrincipal* GetEffectiveStoragePrincipal() override;
|
||||
|
||||
// nsIDOMWindow
|
||||
NS_DECL_NSIDOMWINDOW
|
||||
|
||||
|
@ -1294,6 +1296,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
RefPtr<mozilla::dom::VisualViewport> mVisualViewport;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
|
||||
|
||||
// mTabChild is only ever populated in the content process.
|
||||
nsCOMPtr<nsITabChild> mTabChild;
|
||||
|
||||
|
|
|
@ -476,8 +476,9 @@ class nsOuterWindowProxy : public MaybeCrossOriginObject<js::Wrapper> {
|
|||
* "proxy" is the WindowProxy object involved. It may not be same-compartment
|
||||
* with cx.
|
||||
*/
|
||||
bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandleVector<jsid> props) const override;
|
||||
bool getOwnEnumerablePropertyKeys(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandleVector<jsid> props) const override;
|
||||
|
||||
/**
|
||||
* Hook used by SpiderMonkey to implement Object.prototype.toString.
|
||||
|
@ -733,9 +734,9 @@ bool nsOuterWindowProxy::definePropertySameOrigin(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool nsOuterWindowProxy::ownPropertyKeys(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandleVector<jsid> props) const {
|
||||
bool nsOuterWindowProxy::ownPropertyKeys(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandleVector<jsid> props) const {
|
||||
// Just our indexed stuff followed by our "normal" own property names.
|
||||
if (!AppendIndexedPropertyNames(proxy, props)) {
|
||||
return false;
|
||||
|
@ -938,7 +939,8 @@ bool nsOuterWindowProxy::set(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
}
|
||||
|
||||
bool nsOuterWindowProxy::getOwnEnumerablePropertyKeys(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy, JS::MutableHandleVector<jsid> props) const {
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandleVector<jsid> props) const {
|
||||
// We could just stop overring getOwnEnumerablePropertyKeys and let our
|
||||
// superclasses deal (by falling back on the BaseProxyHandler implementation
|
||||
// that uses a combination of ownPropertyKeys and getOwnPropertyDescriptor to
|
||||
|
@ -1401,6 +1403,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowOuter)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedDoc)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)
|
||||
|
||||
// Traverse stuff from nsPIDOMWindow
|
||||
|
@ -1427,6 +1430,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowOuter)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedDoc)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
|
||||
|
||||
// Unlink stuff from nsPIDOMWindow
|
||||
|
@ -1894,6 +1898,8 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
|||
bool aForceReuseInnerWindow) {
|
||||
MOZ_ASSERT(mDocumentPrincipal == nullptr,
|
||||
"mDocumentPrincipal prematurely set!");
|
||||
MOZ_ASSERT(mDocumentStoragePrincipal == nullptr,
|
||||
"mDocumentStoragePrincipal prematurely set!");
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
// Bail out early if we're in process of closing down the window.
|
||||
|
@ -2446,6 +2452,7 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
|
|||
|
||||
// Remember the document's principal and URI.
|
||||
mDocumentPrincipal = mDoc->NodePrincipal();
|
||||
mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
|
||||
mDocumentURI = mDoc->GetDocumentURI();
|
||||
|
||||
// Release our document reference
|
||||
|
@ -2761,6 +2768,29 @@ nsIPrincipal* nsGlobalWindowOuter::GetPrincipal() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIPrincipal* nsGlobalWindowOuter::GetEffectiveStoragePrincipal() {
|
||||
if (mDoc) {
|
||||
// If we have a document, get the principal from the document
|
||||
return mDoc->EffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
if (mDocumentStoragePrincipal) {
|
||||
return mDocumentStoragePrincipal;
|
||||
}
|
||||
|
||||
// If we don't have a storage principal and we don't have a document we ask
|
||||
// the parent window for the storage principal.
|
||||
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
|
||||
do_QueryInterface(GetParentInternal());
|
||||
|
||||
if (objPrincipal) {
|
||||
return objPrincipal->GetEffectiveStoragePrincipal();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindowOuter::nsIDOMWindow
|
||||
//*****************************************************************************
|
||||
|
|
|
@ -247,6 +247,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
// nsIScriptObjectPrincipal
|
||||
virtual nsIPrincipal* GetPrincipal() override;
|
||||
|
||||
virtual nsIPrincipal* GetEffectiveStoragePrincipal() override;
|
||||
|
||||
// nsIDOMWindow
|
||||
NS_DECL_NSIDOMWINDOW
|
||||
|
||||
|
@ -1098,6 +1100,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
RefPtr<mozilla::dom::Storage> mLocalStorage;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t mSerial;
|
||||
|
|
|
@ -26,6 +26,8 @@ class nsIScriptObjectPrincipal : public nsISupports {
|
|||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTOBJECTPRINCIPAL_IID)
|
||||
|
||||
virtual nsIPrincipal* GetPrincipal() = 0;
|
||||
|
||||
virtual nsIPrincipal* GetEffectiveStoragePrincipal() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptObjectPrincipal,
|
||||
|
|
|
@ -222,10 +222,11 @@ void nsHTMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
|||
}
|
||||
|
||||
void nsHTMLDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) {
|
||||
mLoadFlags = nsIRequest::LOAD_NORMAL;
|
||||
|
||||
Document::ResetToURI(aURI, aLoadGroup, aPrincipal);
|
||||
Document::ResetToURI(aURI, aLoadGroup, aPrincipal, aStoragePrincipal);
|
||||
|
||||
mImages = nullptr;
|
||||
mApplets = nullptr;
|
||||
|
|
|
@ -56,7 +56,8 @@ class nsHTMLDocument : public mozilla::dom::Document, public nsIHTMLDocument {
|
|||
// Document
|
||||
virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override;
|
||||
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) override;
|
||||
|
||||
virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* https://wicg.github.io/feature-policy/#policy
|
||||
*/
|
||||
|
||||
interface Principal;
|
||||
interface WindowProxy;
|
||||
interface nsISupports;
|
||||
interface URI;
|
||||
|
@ -358,6 +359,10 @@ partial interface Document {
|
|||
[CEReactions, NewObject, Throws, Func="IsChromeOrXBL"]
|
||||
Element createXULElement(DOMString localName, optional (ElementCreationOptions or DOMString) options);
|
||||
|
||||
// The principal to use for the storage area of this document
|
||||
[ChromeOnly]
|
||||
readonly attribute Principal effectiveStoragePrincipal;
|
||||
|
||||
// Touch bits
|
||||
// XXXbz I can't find the sane spec for this stuff, so just cribbing
|
||||
// from our xpidl for now.
|
||||
|
|
|
@ -129,7 +129,7 @@ nsresult NS_NewDOMDocument(Document** aInstancePtrResult,
|
|||
d->SetLoadedAsData(aLoadedAsData);
|
||||
d->SetDocumentURI(aDocumentURI);
|
||||
// Must set the principal first, since SetBaseURI checks it.
|
||||
d->SetPrincipal(aPrincipal);
|
||||
d->SetPrincipals(aPrincipal, aPrincipal);
|
||||
d->SetBaseURI(aBaseURI);
|
||||
|
||||
// We need to set the script handling object after we set the principal such
|
||||
|
@ -252,14 +252,15 @@ void XMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
|||
}
|
||||
|
||||
void XMLDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) {
|
||||
if (mChannelIsPending) {
|
||||
StopDocumentLoad();
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
mChannelIsPending = false;
|
||||
}
|
||||
|
||||
Document::ResetToURI(aURI, aLoadGroup, aPrincipal);
|
||||
Document::ResetToURI(aURI, aLoadGroup, aPrincipal, aStoragePrincipal);
|
||||
}
|
||||
|
||||
bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType,
|
||||
|
@ -274,6 +275,7 @@ bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType,
|
|||
|
||||
nsCOMPtr<Document> callingDoc = GetEntryDocument();
|
||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal = EffectiveStoragePrincipal();
|
||||
|
||||
// The callingDoc's Principal and doc's Principal should be the same
|
||||
if (callingDoc && (callingDoc->NodePrincipal() != principal)) {
|
||||
|
@ -370,7 +372,7 @@ bool XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType,
|
|||
loadGroup = callingDoc->GetDocumentLoadGroup();
|
||||
}
|
||||
|
||||
ResetToURI(uri, loadGroup, principal);
|
||||
ResetToURI(uri, loadGroup, principal, storagePrincipal);
|
||||
|
||||
mListenerManager = elm;
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ class XMLDocument : public Document {
|
|||
|
||||
virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override;
|
||||
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) override;
|
||||
|
||||
virtual void SetSuppressParserErrorElement(bool aSuppress) override;
|
||||
virtual bool SuppressParserErrorElement() override;
|
||||
|
|
|
@ -46,6 +46,7 @@ void URIUtils::resolveHref(const nsAString& href, const nsAString& base,
|
|||
void URIUtils::ResetWithSource(Document* aNewDoc, nsINode* aSourceNode) {
|
||||
nsCOMPtr<Document> sourceDoc = aSourceNode->OwnerDoc();
|
||||
nsIPrincipal* sourcePrincipal = sourceDoc->NodePrincipal();
|
||||
nsIPrincipal* sourceStoragePrincipal = sourceDoc->EffectiveStoragePrincipal();
|
||||
|
||||
// Copy the channel and loadgroup from the source document.
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = sourceDoc->GetDocumentLoadGroup();
|
||||
|
@ -66,7 +67,7 @@ void URIUtils::ResetWithSource(Document* aNewDoc, nsINode* aSourceNode) {
|
|||
}
|
||||
|
||||
aNewDoc->Reset(channel, loadGroup);
|
||||
aNewDoc->SetPrincipal(sourcePrincipal);
|
||||
aNewDoc->SetPrincipals(sourcePrincipal, sourceStoragePrincipal);
|
||||
aNewDoc->SetBaseURI(sourceDoc->GetDocBaseURI());
|
||||
|
||||
// Copy charset
|
||||
|
|
|
@ -193,7 +193,8 @@ void XULDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
|||
}
|
||||
|
||||
void XULDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) {
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) {
|
||||
MOZ_ASSERT_UNREACHABLE("ResetToURI");
|
||||
}
|
||||
|
||||
|
@ -242,10 +243,21 @@ nsresult XULDocument::StartDocumentLoad(const char* aCommand,
|
|||
|
||||
// Get the document's principal
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
|
||||
mChannel, getter_AddRefs(principal));
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal;
|
||||
rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipals(
|
||||
mChannel, getter_AddRefs(principal), getter_AddRefs(storagePrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool equal = principal->Equals(storagePrincipal);
|
||||
|
||||
principal = MaybeDowngradePrincipal(principal);
|
||||
SetPrincipal(principal);
|
||||
if (equal) {
|
||||
storagePrincipal = principal;
|
||||
} else {
|
||||
storagePrincipal = MaybeDowngradePrincipal(storagePrincipal);
|
||||
}
|
||||
|
||||
SetPrincipals(principal, storagePrincipal);
|
||||
|
||||
ResetStylesheetsToURI(mDocumentURI);
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ class XULDocument final : public XMLDocument {
|
|||
// Document interface
|
||||
virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) override;
|
||||
virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal* aStoragePrincipal) override;
|
||||
|
||||
virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* channel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
|
|
|
@ -29,6 +29,10 @@ class BackstagePass : public nsIGlobalObject,
|
|||
|
||||
virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
|
||||
|
||||
virtual nsIPrincipal* GetEffectiveStoragePrincipal() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual JSObject* GetGlobalJSObject() override;
|
||||
|
||||
void ForgetGlobalObject() { mWrapper = nullptr; }
|
||||
|
|
|
@ -45,6 +45,8 @@ class SandboxPrivate : public nsIGlobalObject,
|
|||
|
||||
nsIPrincipal* GetPrincipal() override { return mPrincipal; }
|
||||
|
||||
nsIPrincipal* GetEffectiveStoragePrincipal() override { return nullptr; }
|
||||
|
||||
JSObject* GetGlobalJSObject() override { return GetWrapper(); }
|
||||
|
||||
void ForgetGlobalObject(JSObject* obj) { ClearWrapper(obj); }
|
||||
|
|
|
@ -277,7 +277,7 @@ already_AddRefed<Document> nsContentDLF::CreateBlankDocument(
|
|||
if (!uri) {
|
||||
return nullptr;
|
||||
}
|
||||
blankDoc->ResetToURI(uri, aLoadGroup, aPrincipal);
|
||||
blankDoc->ResetToURI(uri, aLoadGroup, aPrincipal, aPrincipal);
|
||||
blankDoc->SetContainer(aContainer);
|
||||
|
||||
// add some simple content structure
|
||||
|
|
|
@ -2233,6 +2233,12 @@ VARCACHE_PREF(
|
|||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
"privacy.storagePrincipal.enabledForTrackers",
|
||||
privacy_storagePrincipal_enabledForTrackers,
|
||||
RelaxedAtomicBool, false
|
||||
)
|
||||
|
||||
// Password protection
|
||||
VARCACHE_PREF(
|
||||
"browser.safebrowsing.passwords.enabled",
|
||||
|
|
|
@ -189,6 +189,12 @@ LoadInfo::LoadInfo(
|
|||
!nsContentUtils::IsInPrivateBrowsing(doc))) {
|
||||
mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal();
|
||||
}
|
||||
|
||||
// If this is the first level iframe, innerWindow is our top-level
|
||||
// principal.
|
||||
if (!mTopLevelPrincipal) {
|
||||
mTopLevelPrincipal = innerWindow->GetPrincipal();
|
||||
}
|
||||
}
|
||||
|
||||
mDocumentHasLoaded = innerWindow->IsDocumentLoaded();
|
||||
|
|
|
@ -84,7 +84,8 @@ PrototypeDocumentParser::Parse(nsIURI* aURL, nsIRequestObserver* aListener,
|
|||
mCurrentPrototype = proto;
|
||||
|
||||
// Set up the right principal on the document.
|
||||
mDocument->SetPrincipal(proto->DocumentPrincipal());
|
||||
mDocument->SetPrincipals(proto->DocumentPrincipal(),
|
||||
proto->DocumentPrincipal());
|
||||
} else {
|
||||
// It's just a vanilla document load. Create a parser to deal
|
||||
// with the stream n' stuff.
|
||||
|
@ -185,7 +186,7 @@ nsresult PrototypeDocumentParser::PrepareToLoadPrototype(
|
|||
nsXULPrototypeCache::GetInstance()->PutPrototype(mCurrentPrototype);
|
||||
}
|
||||
|
||||
mDocument->SetPrincipal(aDocumentPrincipal);
|
||||
mDocument->SetPrincipals(aDocumentPrincipal, aDocumentPrincipal);
|
||||
|
||||
// Create a XUL content sink, a parser, and kick off a load for
|
||||
// the document.
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "StoragePrincipalHelper.h"
|
||||
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// static
|
||||
nsresult StoragePrincipalHelper::Create(nsIChannel* aChannel,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal** aStoragePrincipal) {
|
||||
MOZ_ASSERT(aChannel);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(aStoragePrincipal);
|
||||
|
||||
auto scopeExit = MakeScopeExit([&] {
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal = aPrincipal;
|
||||
storagePrincipal.forget(aStoragePrincipal);
|
||||
});
|
||||
|
||||
if (!StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Let's use the storage principal only if we need to partition the cookie
|
||||
// jar.
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForChannel(aChannel);
|
||||
if (access != nsContentUtils::StorageAccess::ePartitionedOrDeny) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
||||
if (!httpChannel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(httpChannel->IsThirdPartyTrackingResource());
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
nsCOMPtr<nsIPrincipal> toplevelPrincipal = loadInfo->GetTopLevelPrincipal();
|
||||
if (!toplevelPrincipal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> principalURI;
|
||||
nsresult rv = toplevelPrincipal->GetURI(getter_AddRefs(principalURI));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
scopeExit.release();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal =
|
||||
BasePrincipal::Cast(aPrincipal)
|
||||
->CloneForcingFirstPartyDomain(principalURI);
|
||||
|
||||
storagePrincipal.forget(aStoragePrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,23 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_StoragePrincipalHelper_h
|
||||
#define mozilla_StoragePrincipalHelper_h
|
||||
|
||||
class nsIChannel;
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class StoragePrincipalHelper final {
|
||||
public:
|
||||
static nsresult Create(nsIChannel* aChannel, nsIPrincipal* aPrincipal,
|
||||
nsIPrincipal** aStoragePrincipal);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_StoragePrincipalHelper_h
|
|
@ -9,10 +9,12 @@ with Files('**'):
|
|||
|
||||
EXPORTS.mozilla = [
|
||||
'AntiTrackingCommon.h',
|
||||
'StoragePrincipalHelper.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AntiTrackingCommon.cpp',
|
||||
'StoragePrincipalHelper.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
Загрузка…
Ссылка в новой задаче