Backed out 11 changesets (bug 1475599) for causing wpt failures on change_eventhandler_in_bfcache.https.window.html. CLOSED TREE

Backed out changeset 74d0efb3b0d1 (bug 1475599)
Backed out changeset 7e736b5732c1 (bug 1475599)
Backed out changeset 8620daea37ad (bug 1475599)
Backed out changeset 0d57b435d872 (bug 1475599)
Backed out changeset a63a5bcb0524 (bug 1475599)
Backed out changeset cd8cc80dc7e9 (bug 1475599)
Backed out changeset ef2cdfb059af (bug 1475599)
Backed out changeset d3c7729a1972 (bug 1475599)
Backed out changeset 7eccbaa8e62e (bug 1475599)
Backed out changeset cc3c39aa8fb8 (bug 1475599)
Backed out changeset 2fc9a3d0ad8b (bug 1475599)
This commit is contained in:
Iulian Moraru 2024-09-12 00:03:14 +03:00
parent 4b5a314baa
commit 07f06ae72b
93 changed files with 971 additions and 3372 deletions

View File

@ -6551,28 +6551,43 @@ void Document::GetCookie(nsAString& aCookie, ErrorResult& aRv) {
aCookie.Truncate(); // clear current cookie in case service fails;
// no cookie isn't an error condition.
nsCOMPtr<nsIPrincipal> cookiePrincipal;
nsCOMPtr<nsIPrincipal> cookiePartitionedPrincipal;
if (mDisableCookieAccess) {
return;
}
CookieCommons::SecurityChecksResult checkResult =
CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
this, getter_AddRefs(cookiePrincipal),
getter_AddRefs(cookiePartitionedPrincipal));
switch (checkResult) {
case CookieCommons::SecurityChecksResult::eSandboxedError:
aRv.ThrowSecurityError(
"Forbidden in a sandboxed document without the 'allow-same-origin' "
"flag.");
// If the document's sandboxed origin flag is set, then reading cookies
// is prohibited.
if (mSandboxFlags & SANDBOXED_ORIGIN) {
aRv.ThrowSecurityError(
"Forbidden in a sandboxed document without the 'allow-same-origin' "
"flag.");
return;
}
// GTests do not create an inner window and because of these a few security
// checks will block this method.
if (!StaticPrefs::dom_cookie_testing_enabled()) {
StorageAccess storageAccess = CookieAllowedForDocument(this);
if (storageAccess == StorageAccess::eDeny) {
return;
}
case CookieCommons::SecurityChecksResult::eSecurityError:
[[fallthrough]];
case CookieCommons::SecurityChecksResult::eDoNotContinue:
if (ShouldPartitionStorage(storageAccess) &&
!StoragePartitioningEnabled(storageAccess, CookieJarSettings())) {
return;
}
case CookieCommons::SecurityChecksResult::eContinue:
break;
// If the document is a cookie-averse Document... return the empty string.
if (IsCookieAverse()) {
return;
}
}
// not having a cookie service isn't an error
nsCOMPtr<nsICookieService> service =
do_GetService(NS_COOKIESERVICE_CONTRACTID);
if (!service) {
return;
}
bool thirdParty = true;
@ -6588,13 +6603,35 @@ void Document::GetCookie(nsAString& aCookie, ErrorResult& aRv) {
}
}
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
nsCOMPtr<nsIPrincipal> cookiePrincipal = EffectiveCookiePrincipal();
MOZ_ASSERT(cookiePrincipal);
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
principals.AppendElement(cookiePrincipal);
if (cookiePartitionedPrincipal) {
principals.AppendElement(cookiePartitionedPrincipal);
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
// (and therefore the partitioned principal), the unpartitioned cookie jar is
// only available in first-party or third-party with storageAccess contexts.
// In both cases, the document will have storage access.
bool isCHIPS = StaticPrefs::network_cookie_CHIPS_enabled() &&
CookieJarSettings()->GetPartitionForeign();
bool documentHasStorageAccess = false;
nsresult rv = HasStorageAccessSync(documentHasStorageAccess);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
if (isCHIPS && documentHasStorageAccess) {
// Assert that the cookie principal is unpartitioned.
MOZ_ASSERT(cookiePrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
// Only append the partitioned originAttributes if the partitionKey is set.
// The partitionKey could be empty for partitionKey in partitioned
// originAttributes if the document is for privilege context, such as the
// extension's background page.
if (!PartitionedPrincipal()
->OriginAttributesRef()
.mPartitionKey.IsEmpty()) {
principals.AppendElement(PartitionedPrincipal());
}
}
nsTArray<RefPtr<Cookie>> cookieList;
@ -6602,16 +6639,13 @@ void Document::GetCookie(nsAString& aCookie, ErrorResult& aRv) {
int64_t currentTimeInUsec = PR_Now();
int64_t currentTime = currentTimeInUsec / PR_USEC_PER_SEC;
// not having a cookie service isn't an error
nsCOMPtr<nsICookieService> service =
do_GetService(NS_COOKIESERVICE_CONTRACTID);
if (!service) {
return;
}
for (auto& principal : principals) {
if (!CookieCommons::IsSchemeSupported(principal)) {
return;
}
nsAutoCString baseDomain;
nsresult rv = CookieCommons::GetBaseDomain(principal, baseDomain);
rv = CookieCommons::GetBaseDomain(principal, baseDomain);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -6653,9 +6687,8 @@ void Document::GetCookie(nsAString& aCookie, ErrorResult& aRv) {
continue;
}
if (thirdParty && !CookieCommons::ShouldIncludeCrossSiteCookie(
cookie, CookieJarSettings()->GetPartitionForeign(),
IsInPrivateBrowsing(), UsingStorageAccess())) {
if (thirdParty && !CookieCommons::ShouldIncludeCrossSiteCookieForDocument(
cookie, this)) {
continue;
}
@ -6707,26 +6740,32 @@ void Document::GetCookie(nsAString& aCookie, ErrorResult& aRv) {
}
void Document::SetCookie(const nsAString& aCookieString, ErrorResult& aRv) {
nsCOMPtr<nsIPrincipal> cookiePrincipal;
if (mDisableCookieAccess) {
return;
}
CookieCommons::SecurityChecksResult checkResult =
CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
this, getter_AddRefs(cookiePrincipal), nullptr);
switch (checkResult) {
case CookieCommons::SecurityChecksResult::eSandboxedError:
aRv.ThrowSecurityError(
"Forbidden in a sandboxed document without the 'allow-same-origin' "
"flag.");
return;
// If the document's sandboxed origin flag is set, then setting cookies
// is prohibited.
if (mSandboxFlags & SANDBOXED_ORIGIN) {
aRv.ThrowSecurityError(
"Forbidden in a sandboxed document without the 'allow-same-origin' "
"flag.");
return;
}
case CookieCommons::SecurityChecksResult::eSecurityError:
[[fallthrough]];
StorageAccess storageAccess = CookieAllowedForDocument(this);
if (storageAccess == StorageAccess::eDeny) {
return;
}
case CookieCommons::SecurityChecksResult::eDoNotContinue:
return;
if (ShouldPartitionStorage(storageAccess) &&
!StoragePartitioningEnabled(storageAccess, CookieJarSettings())) {
return;
}
case CookieCommons::SecurityChecksResult::eContinue:
break;
// If the document is a cookie-averse Document... do nothing.
if (IsCookieAverse()) {
return;
}
if (!mDocumentURI) {
@ -6790,9 +6829,8 @@ void Document::SetCookie(const nsAString& aCookieString, ErrorResult& aRv) {
nullptr, &thirdParty);
}
if (thirdParty && !CookieCommons::ShouldIncludeCrossSiteCookie(
cookie, CookieJarSettings()->GetPartitionForeign(),
IsInPrivateBrowsing(), UsingStorageAccess())) {
if (thirdParty &&
!CookieCommons::ShouldIncludeCrossSiteCookieForDocument(cookie, this)) {
return;
}

View File

@ -1098,8 +1098,6 @@ class Document : public nsINode,
*/
void DisableCookieAccess() { mDisableCookieAccess = true; }
bool CookieAccessDisabled() const { return mDisableCookieAccess; }
void SetLinkHandlingEnabled(bool aValue) { mLinksEnabled = aValue; }
bool LinkHandlingEnabled() { return mLinksEnabled; }

View File

@ -108,7 +108,6 @@
#include "mozilla/dom/ClientState.h"
#include "mozilla/dom/ClientsBinding.h"
#include "mozilla/dom/Console.h"
#include "mozilla/dom/CookieStore.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentFrameMessageManager.h"
#include "mozilla/dom/ContentMediaController.h"
@ -1261,7 +1260,6 @@ void nsGlobalWindowInner::FreeInnerObjects() {
mScrollbars = nullptr;
mConsole = nullptr;
mCookieStore = nullptr;
mPaintWorklet = nullptr;
@ -1452,7 +1450,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCookieStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInstallTrigger)
@ -1565,7 +1562,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCookieStore)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPaintWorklet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mInstallTrigger)
@ -5932,10 +5928,6 @@ nsresult nsGlobalWindowInner::FireDelayedDOMEvents(bool aIncludeSubWindows) {
// Fires an offline status event if the offline status has changed
FireOfflineStatusEventIfChanged();
if (mCookieStore) {
mCookieStore->FireDelayedDOMEvents();
}
if (!aIncludeSubWindows) {
return NS_OK;
}
@ -7294,14 +7286,6 @@ already_AddRefed<Console> nsGlobalWindowInner::GetConsole(JSContext* aCx,
return console.forget();
}
already_AddRefed<CookieStore> nsGlobalWindowInner::CookieStore() {
if (!mCookieStore) {
mCookieStore = CookieStore::Create(this);
}
return do_AddRef(mCookieStore);
}
bool nsGlobalWindowInner::IsSecureContext() const {
JS::Realm* realm = js::GetNonCCWObjectRealm(GetWrapperPreserveColor());
return JS::GetIsSecureContext(realm);

View File

@ -104,7 +104,6 @@ struct ChannelPixelLayout;
class Credential;
class ClientSource;
class Console;
class CookieStore;
class Crypto;
class CustomElementRegistry;
class DataTransfer;
@ -655,8 +654,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
already_AddRefed<mozilla::dom::Console> GetConsole(JSContext* aCx,
mozilla::ErrorResult& aRv);
already_AddRefed<mozilla::dom::CookieStore> CookieStore();
// https://w3c.github.io/webappsec-secure-contexts/#dom-window-issecurecontext
bool IsSecureContext() const;
@ -1377,7 +1374,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
RefPtr<mozilla::dom::Crypto> mCrypto;
RefPtr<mozilla::dom::cache::CacheStorage> mCacheStorage;
RefPtr<mozilla::dom::Console> mConsole;
RefPtr<mozilla::dom::CookieStore> mCookieStore;
RefPtr<mozilla::dom::Worklet> mPaintWorklet;
RefPtr<mozilla::dom::External> mExternal;
RefPtr<mozilla::dom::InstallTriggerImpl> mInstallTrigger;

View File

@ -1,79 +0,0 @@
/* -*- 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 "mozilla/dom/CookieChangeEvent.h"
#include "mozilla/dom/CookieChangeEventBinding.h"
namespace mozilla::dom {
CookieChangeEvent::CookieChangeEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent)
: Event(aOwner, aPresContext, aEvent) {}
CookieChangeEvent::~CookieChangeEvent() = default;
JSObject* CookieChangeEvent::WrapObjectInternal(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
return mozilla::dom::CookieChangeEvent_Binding::Wrap(aCx, this, aGivenProto);
}
void CookieChangeEvent::GetChanged(nsTArray<CookieListItem>& aList) const {
aList = mChanged.Clone();
}
void CookieChangeEvent::GetDeleted(nsTArray<CookieListItem>& aList) const {
aList = mDeleted.Clone();
}
/* static */ already_AddRefed<CookieChangeEvent> CookieChangeEvent::Constructor(
const GlobalObject& aGlobal, const nsAString& aType,
const CookieChangeEventInit& aEventInit) {
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<CookieChangeEvent> event = new CookieChangeEvent(t, nullptr, nullptr);
bool trusted = event->Init(t);
event->InitEvent(aType, aEventInit.mBubbles, aEventInit.mCancelable);
event->SetTrusted(trusted);
if (aEventInit.mChanged.WasPassed()) {
event->mChanged = aEventInit.mChanged.Value();
}
if (aEventInit.mDeleted.WasPassed()) {
event->mDeleted = aEventInit.mDeleted.Value();
}
return event.forget();
}
/* static */ already_AddRefed<CookieChangeEvent>
CookieChangeEvent::CreateForChangedCookie(EventTarget* aEventTarget,
const CookieListItem& aItem) {
RefPtr<CookieChangeEvent> event =
new CookieChangeEvent(aEventTarget, nullptr, nullptr);
event->InitEvent(u"change"_ns, false, false);
event->SetTrusted(true);
event->mChanged.AppendElement(aItem);
return event.forget();
}
/* static */ already_AddRefed<CookieChangeEvent>
CookieChangeEvent::CreateForDeletedCookie(EventTarget* aEventTarget,
const CookieListItem& aItem) {
RefPtr<CookieChangeEvent> event =
new CookieChangeEvent(aEventTarget, nullptr, nullptr);
event->InitEvent(u"change"_ns, false, false);
event->SetTrusted(true);
event->mDeleted.AppendElement(aItem);
return event.forget();
}
} // namespace mozilla::dom

View File

@ -1,47 +0,0 @@
/* -*- 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_dom_CookieChangeEvent_h
#define mozilla_dom_CookieChangeEvent_h
#include "mozilla/dom/Event.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CookieChangeEventBinding.h"
namespace mozilla::dom {
class CookieChangeEvent final : public Event {
public:
CookieChangeEvent(EventTarget* aOwner, nsPresContext* aPresContext,
WidgetEvent* aEvent);
JSObject* WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<CookieChangeEvent> Constructor(
const GlobalObject& aGlobal, const nsAString& aType,
const CookieChangeEventInit& aEventInit);
void GetChanged(nsTArray<CookieListItem>& aList) const;
void GetDeleted(nsTArray<CookieListItem>& aList) const;
static already_AddRefed<CookieChangeEvent> CreateForChangedCookie(
EventTarget* aEventTarget, const CookieListItem& aItem);
static already_AddRefed<CookieChangeEvent> CreateForDeletedCookie(
EventTarget* aEventTarget, const CookieListItem& aItem);
private:
~CookieChangeEvent();
nsTArray<CookieListItem> mChanged;
nsTArray<CookieListItem> mDeleted;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_CookieChangeEvent_h */

View File

@ -1,776 +0,0 @@
/* -*- 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 "CookieStore.h"
#include "CookieStoreChild.h"
#include "CookieStoreNotifier.h"
#include "CookieStoreNotificationWatcherWrapper.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/net/CookieCommons.h"
#include "mozilla/StorageAccess.h"
#include "nsICookie.h"
#include "nsIGlobalObject.h"
#include "nsIPrincipal.h"
#include "nsReadableUtils.h"
#include "nsSandboxFlags.h"
#include "ThirdPartyUtil.h"
using namespace mozilla::net;
namespace mozilla::dom {
namespace {
int32_t SameSiteToConst(const CookieSameSite& aSameSite) {
switch (aSameSite) {
case CookieSameSite::Strict:
return nsICookie::SAMESITE_STRICT;
case CookieSameSite::Lax:
return nsICookie::SAMESITE_LAX;
default:
MOZ_ASSERT(aSameSite == CookieSameSite::None);
return nsICookie::SAMESITE_NONE;
}
}
bool ValidateCookieNameOrValue(const nsAString& aStr) {
for (auto iter = aStr.BeginReading(), end = aStr.EndReading(); iter < end;
++iter) {
if (*iter == 0x3B || *iter == 0x7F || (*iter <= 0x1F && *iter != 0x09)) {
return false;
}
}
return true;
}
bool ValidateCookieNameAndValue(const nsAString& aName, const nsAString& aValue,
Promise* aPromise) {
MOZ_ASSERT(aPromise);
if (!ValidateCookieNameOrValue(aName)) {
aPromise->MaybeRejectWithTypeError("Cookie name contains invalid chars");
return false;
}
if (!ValidateCookieNameOrValue(aValue)) {
aPromise->MaybeRejectWithTypeError("Cookie value contains invalid chars");
return false;
}
if (aName.IsEmpty() && aValue.Contains('=')) {
aPromise->MaybeRejectWithTypeError(
"Cookie value cannot contain '=' if the name is empty");
return false;
}
if (aName.IsEmpty() && aValue.IsEmpty()) {
aPromise->MaybeRejectWithTypeError(
"Cookie name and value both cannot be empty");
return false;
}
if (aName.Length() + aValue.Length() > 1024) {
aPromise->MaybeRejectWithTypeError(
"Cookie name and value size cannot be greater than 1024 bytes");
return false;
}
return true;
}
bool ValidateCookieDomain(const nsAString& aHost, const nsAString& aDomain,
Promise* aPromise) {
MOZ_ASSERT(aPromise);
if (aDomain.IsEmpty()) {
return true;
}
if (aDomain[0] == '.') {
aPromise->MaybeRejectWithTypeError("Cookie domain cannot start with '.'");
return false;
}
if (aHost != aDomain) {
if ((aHost.Length() < aDomain.Length() + 1) ||
!StringEndsWith(aHost, aDomain) ||
aHost[aHost.Length() - aDomain.Length() - 1] != '.') {
aPromise->MaybeRejectWithTypeError(
"Cookie domain must domain-match current host");
return false;
}
}
if (aDomain.Length() > 1024) {
aPromise->MaybeRejectWithTypeError(
"Cookie domain size cannot be greater than 1024 bytes");
return false;
}
return true;
}
bool ValidateCookiePath(const nsAString& aPath, nsAString& retPath,
Promise* aPromise) {
MOZ_ASSERT(aPromise);
if (!aPath.IsEmpty() && aPath[0] != '/') {
aPromise->MaybeRejectWithTypeError("Cookie path must start with '/'");
return false;
}
nsString path(aPath);
if (path.IsEmpty() || path[path.Length() - 1] != '/') {
path.Append('/');
}
if (path.Length() > 1024) {
aPromise->MaybeRejectWithTypeError(
"Cookie domain size cannot be greater than 1024 bytes");
return false;
}
retPath.Assign(path);
return true;
}
// Reject cookies whose name starts with the magic prefixes from
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis
// if they do not meet the criteria required by the prefix.
bool ValidateCookieNamePrefix(const nsAString& aName,
const nsAString& aOptionDomain,
const nsAString& aPath, Promise* aPromise) {
MOZ_ASSERT(aPromise);
if (!StringBeginsWith(aName, u"__Host-"_ns,
nsCaseInsensitiveStringComparator)) {
return true;
}
if (!aOptionDomain.IsEmpty()) {
aPromise->MaybeRejectWithTypeError(
"Cookie domain cannot be used when the cookie name uses special "
"prefixes");
return false;
}
if (!aPath.EqualsLiteral("/")) {
aPromise->MaybeRejectWithTypeError(
"Cookie path cannot be different than '/' when the cookie name uses "
"special prefixes");
return false;
}
return true;
}
void CookieDataToItem(const CookieData& aData, CookieListItem* aItem) {
aItem->mName.Construct(aData.name());
aItem->mValue.Construct(aData.value());
}
void CookieDataToList(const nsTArray<CookieData>& aData,
nsTArray<CookieListItem>& aResult) {
for (const CookieData& data : aData) {
CookieListItem* item = aResult.AppendElement();
CookieDataToItem(data, item);
}
}
void ResolvePromiseAsync(Promise* aPromise) {
MOZ_ASSERT(aPromise);
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
__func__,
[promise = RefPtr(aPromise)] { promise->MaybeResolveWithUndefined(); }));
}
bool GetContextAttributes(CookieStore* aCookieStore, bool* aThirdPartyContext,
bool* aPartitionForeign, bool* aUsingStorageAccess,
Promise* aPromise) {
MOZ_ASSERT(aCookieStore);
MOZ_ASSERT(aThirdPartyContext);
MOZ_ASSERT(aPartitionForeign);
MOZ_ASSERT(aUsingStorageAccess);
MOZ_ASSERT(aPromise);
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = aCookieStore->GetOwnerWindow();
MOZ_ASSERT(window);
ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
if (thirdPartyUtil) {
Unused << thirdPartyUtil->IsThirdPartyWindow(window->GetOuterWindow(),
nullptr, aThirdPartyContext);
}
nsCOMPtr<Document> document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) {
aPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return false;
}
*aPartitionForeign = document->CookieJarSettings()->GetPartitionForeign();
*aUsingStorageAccess = document->UsingStorageAccess();
return true;
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
*aThirdPartyContext = workerPrivate->IsThirdPartyContext();
*aPartitionForeign =
workerPrivate->CookieJarSettings()->GetPartitionForeign();
*aUsingStorageAccess = workerPrivate->UsingStorageAccess();
return true;
}
} // namespace
NS_IMPL_CYCLE_COLLECTION_CLASS(CookieStore)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CookieStore,
DOMEventTargetHelper)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CookieStore,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CookieStore)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(CookieStore, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(CookieStore, DOMEventTargetHelper)
// static
already_AddRefed<CookieStore> CookieStore::Create(nsIGlobalObject* aGlobal) {
return do_AddRef(new CookieStore(aGlobal));
}
CookieStore::CookieStore(nsIGlobalObject* aGlobal)
: DOMEventTargetHelper(aGlobal) {
mNotifier = CookieStoreNotifier::Create(this);
// This must be created _after_ CookieStoreNotifier because we rely on the
// notification order.
mNotificationWatcher = CookieStoreNotificationWatcherWrapper::Create(this);
}
CookieStore::~CookieStore() { Shutdown(); }
JSObject* CookieStore::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return CookieStore_Binding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<Promise> CookieStore::Get(const nsAString& aName,
ErrorResult& aRv) {
CookieStoreGetOptions options;
options.mName.Construct(aName);
return Get(options, aRv);
}
already_AddRefed<Promise> CookieStore::Get(
const CookieStoreGetOptions& aOptions, ErrorResult& aRv) {
return GetInternal(aOptions, true, aRv);
}
already_AddRefed<Promise> CookieStore::GetAll(const nsAString& aName,
ErrorResult& aRv) {
CookieStoreGetOptions options;
options.mName.Construct(aName);
return GetAll(options, aRv);
}
already_AddRefed<Promise> CookieStore::GetAll(
const CookieStoreGetOptions& aOptions, ErrorResult& aRv) {
return GetInternal(aOptions, false, aRv);
}
already_AddRefed<Promise> CookieStore::Set(const nsAString& aName,
const nsAString& aValue,
ErrorResult& aRv) {
CookieInit init;
init.mName = aName;
init.mValue = aValue;
return Set(init, aRv);
}
already_AddRefed<Promise> CookieStore::Set(const CookieInit& aOptions,
ErrorResult& aRv) {
RefPtr<Promise> promise = Promise::Create(GetOwnerGlobal(), aRv);
if (NS_WARN_IF(!promise)) {
return nullptr;
}
nsCOMPtr<nsIPrincipal> cookiePrincipal;
switch (CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
MaybeGetDocument(), getter_AddRefs(cookiePrincipal), nullptr)) {
case CookieCommons::SecurityChecksResult::eSandboxedError:
[[fallthrough]];
case CookieCommons::SecurityChecksResult::eSecurityError:
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
case CookieCommons::SecurityChecksResult::eDoNotContinue:
ResolvePromiseAsync(promise);
return promise.forget();
case CookieCommons::SecurityChecksResult::eContinue:
MOZ_ASSERT(cookiePrincipal);
break;
}
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
__func__, [self = RefPtr(this), promise = RefPtr(promise), aOptions,
cookiePrincipal = RefPtr(cookiePrincipal.get())]() {
if (!ValidateCookieNameAndValue(aOptions.mName, aOptions.mValue,
promise)) {
return;
}
nsAutoCString baseDomainUtf8;
nsresult rv =
net::CookieCommons::GetBaseDomain(cookiePrincipal, baseDomainUtf8);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
NS_ConvertUTF8toUTF16 baseDomain(baseDomainUtf8);
if (!ValidateCookieDomain(baseDomain, aOptions.mDomain, promise)) {
return;
}
nsString path;
if (!ValidateCookiePath(aOptions.mPath, path, promise)) {
return;
}
if (!ValidateCookieNamePrefix(aOptions.mName, aOptions.mDomain, path,
promise)) {
return;
}
bool thirdPartyContext = true;
bool partitionForeign = true;
bool usingStorageAccess = false;
if (!GetContextAttributes(self, &thirdPartyContext, &partitionForeign,
&usingStorageAccess, promise)) {
return;
}
if (!self->MaybeCreateActor()) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
if (!self->mNotificationWatcher) {
promise->MaybeReject(NS_ERROR_UNEXPECTED);
return;
}
nsID operationID;
rv = nsID::GenerateUUIDInPlace(operationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_UNEXPECTED);
return;
}
self->mNotificationWatcher->ResolvePromiseWhenNotified(operationID,
promise);
RefPtr<CookieStoreChild::SetRequestPromise> ipcPromise =
self->mActor->SendSetRequest(
aOptions.mDomain.IsEmpty() ? nsString(baseDomain)
: nsString(aOptions.mDomain),
cookiePrincipal->OriginAttributesRef(), thirdPartyContext,
partitionForeign, usingStorageAccess, nsString(aOptions.mName),
nsString(aOptions.mValue),
// If expires is not set, it's a session cookie.
aOptions.mExpires.IsNull(),
aOptions.mExpires.IsNull()
? INT64_MAX
: static_cast<int64_t>(aOptions.mExpires.Value() / 1000),
path, SameSiteToConst(aOptions.mSameSite),
aOptions.mPartitioned, operationID);
if (NS_WARN_IF(!ipcPromise)) {
promise->MaybeResolveWithUndefined();
return;
}
ipcPromise->Then(
NS_GetCurrentThread(), __func__,
[promise = RefPtr<dom::Promise>(promise), self = RefPtr(self),
operationID](
const CookieStoreChild::SetRequestPromise::ResolveOrRejectValue&
aResult) {
if (!aResult.ResolveValue()) {
self->mNotificationWatcher->ForgetOperationID(operationID);
promise->MaybeResolveWithUndefined();
}
});
}));
return promise.forget();
}
already_AddRefed<Promise> CookieStore::Delete(const nsAString& aName,
ErrorResult& aRv) {
CookieStoreDeleteOptions options;
options.mName = aName;
return Delete(options, aRv);
}
already_AddRefed<Promise> CookieStore::Delete(
const CookieStoreDeleteOptions& aOptions, ErrorResult& aRv) {
RefPtr<Promise> promise = Promise::Create(GetOwnerGlobal(), aRv);
if (NS_WARN_IF(!promise)) {
return nullptr;
}
nsCOMPtr<nsIPrincipal> cookiePrincipal;
switch (CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
MaybeGetDocument(), getter_AddRefs(cookiePrincipal), nullptr)) {
case CookieCommons::SecurityChecksResult::eSandboxedError:
[[fallthrough]];
case CookieCommons::SecurityChecksResult::eSecurityError:
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
case CookieCommons::SecurityChecksResult::eDoNotContinue:
ResolvePromiseAsync(promise);
return promise.forget();
case CookieCommons::SecurityChecksResult::eContinue:
MOZ_ASSERT(cookiePrincipal);
break;
}
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
__func__, [self = RefPtr(this), promise = RefPtr(promise), aOptions,
cookiePrincipal = RefPtr(cookiePrincipal.get())]() {
nsAutoCString baseDomainUtf8;
nsresult rv =
net::CookieCommons::GetBaseDomain(cookiePrincipal, baseDomainUtf8);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
NS_ConvertUTF8toUTF16 baseDomain(baseDomainUtf8);
if (!ValidateCookieDomain(baseDomain, aOptions.mDomain, promise)) {
return;
}
nsString path;
if (!ValidateCookiePath(aOptions.mPath, path, promise)) {
return;
}
if (!ValidateCookieNamePrefix(aOptions.mName, aOptions.mDomain, path,
promise)) {
return;
}
bool thirdPartyContext = true;
bool partitionForeign = true;
bool usingStorageAccess = false;
if (!GetContextAttributes(self, &thirdPartyContext, &partitionForeign,
&usingStorageAccess, promise)) {
return;
}
if (!self->MaybeCreateActor()) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
if (!self->mNotificationWatcher) {
promise->MaybeReject(NS_ERROR_UNEXPECTED);
return;
}
nsID operationID;
rv = nsID::GenerateUUIDInPlace(operationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_UNEXPECTED);
return;
}
self->mNotificationWatcher->ResolvePromiseWhenNotified(operationID,
promise);
RefPtr<CookieStoreChild::DeleteRequestPromise> ipcPromise =
self->mActor->SendDeleteRequest(
aOptions.mDomain.IsEmpty() ? nsString(baseDomain)
: nsString(aOptions.mDomain),
cookiePrincipal->OriginAttributesRef(), thirdPartyContext,
partitionForeign, usingStorageAccess, nsString(aOptions.mName),
path, aOptions.mPartitioned, operationID);
if (NS_WARN_IF(!ipcPromise)) {
promise->MaybeResolveWithUndefined();
return;
}
ipcPromise->Then(
NS_GetCurrentThread(), __func__,
[promise = RefPtr<dom::Promise>(promise), self = RefPtr(self),
operationID](const CookieStoreChild::DeleteRequestPromise::
ResolveOrRejectValue& aResult) {
MOZ_ASSERT(aResult.IsResolve());
if (!aResult.ResolveValue()) {
self->mNotificationWatcher->ForgetOperationID(operationID);
promise->MaybeResolveWithUndefined();
}
});
}));
return promise.forget();
}
void CookieStore::Shutdown() {
if (mActor) {
mActor->Close();
mActor = nullptr;
}
if (mNotifier) {
mNotifier->Disentangle();
mNotifier = nullptr;
}
}
bool CookieStore::MaybeCreateActor() {
if (mActor) {
return mActor->CanSend();
}
mozilla::ipc::PBackgroundChild* actorChild =
mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!actorChild)) {
// The process is probably shutting down. Let's return a 'generic' error.
return false;
}
PCookieStoreChild* actor = actorChild->SendPCookieStoreConstructor();
if (!actor) {
return false;
}
mActor = static_cast<CookieStoreChild*>(actor);
return true;
}
already_AddRefed<Promise> CookieStore::GetInternal(
const CookieStoreGetOptions& aOptions, bool aOnlyTheFirstMatch,
ErrorResult& aRv) {
RefPtr<Promise> promise = Promise::Create(GetOwnerGlobal(), aRv);
if (NS_WARN_IF(!promise)) {
return nullptr;
}
nsCOMPtr<nsIPrincipal> cookiePrincipal;
nsCOMPtr<nsIPrincipal> partitionedCookiePrincipal;
switch (CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
MaybeGetDocument(), getter_AddRefs(cookiePrincipal),
getter_AddRefs(partitionedCookiePrincipal))) {
case CookieCommons::SecurityChecksResult::eSandboxedError:
[[fallthrough]];
case CookieCommons::SecurityChecksResult::eSecurityError:
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
case CookieCommons::SecurityChecksResult::eDoNotContinue:
ResolvePromiseAsync(promise);
return promise.forget();
case CookieCommons::SecurityChecksResult::eContinue:
MOZ_ASSERT(cookiePrincipal);
break;
}
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
__func__,
[self = RefPtr(this), promise = RefPtr(promise), aOptions,
cookiePrincipal = RefPtr(cookiePrincipal.get()),
partitionedCookiePrincipal = RefPtr(partitionedCookiePrincipal.get()),
aOnlyTheFirstMatch]() {
nsAutoString name;
if (aOptions.mName.WasPassed()) {
name = aOptions.mName.Value();
}
nsAutoCString path;
nsresult rv = cookiePrincipal->GetFilePath(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return;
}
if (aOptions.mUrl.WasPassed()) {
nsString url(aOptions.mUrl.Value());
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = self->GetOwnerWindow();
MOZ_ASSERT(window);
nsCOMPtr<Document> document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) {
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsIURI* creationURI = document->GetOriginalURI();
if (NS_WARN_IF(!creationURI)) {
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsIURI> resolvedURI;
rv = NS_NewURI(getter_AddRefs(resolvedURI), url, nullptr,
creationURI);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
NS_ConvertUTF16toUTF8(url));
return;
}
bool equal = false;
if (!resolvedURI ||
NS_WARN_IF(NS_FAILED(
resolvedURI->EqualsExceptRef(creationURI, &equal))) ||
!equal) {
promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
NS_ConvertUTF16toUTF8(url));
return;
}
} else {
nsCOMPtr<nsIURI> baseURI = cookiePrincipal->GetURI();
if (NS_WARN_IF(!baseURI)) {
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsIURI> resolvedURI;
rv = NS_NewURI(getter_AddRefs(resolvedURI), url, nullptr, baseURI);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
NS_ConvertUTF16toUTF8(url));
return;
}
if (!cookiePrincipal->IsSameOrigin(resolvedURI)) {
promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
NS_ConvertUTF16toUTF8(url));
return;
}
rv = resolvedURI->GetFilePath(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return;
}
}
}
bool thirdPartyContext = true;
bool partitionForeign = true;
bool usingStorageAccess = false;
if (!GetContextAttributes(self, &thirdPartyContext, &partitionForeign,
&usingStorageAccess, promise)) {
return;
}
if (!self->MaybeCreateActor()) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
nsAutoCString baseDomain;
rv = net::CookieCommons::GetBaseDomain(cookiePrincipal, baseDomain);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeRejectWithNotAllowedError("Permission denied");
return;
}
RefPtr<CookieStoreChild::GetRequestPromise> ipcPromise =
self->mActor->SendGetRequest(
NS_ConvertUTF8toUTF16(baseDomain),
cookiePrincipal->OriginAttributesRef(),
partitionedCookiePrincipal
? Some(partitionedCookiePrincipal->OriginAttributesRef())
: Nothing(),
thirdPartyContext, partitionForeign, usingStorageAccess,
aOptions.mName.WasPassed(), nsString(name), path,
aOnlyTheFirstMatch);
if (NS_WARN_IF(!ipcPromise)) {
promise->MaybeResolveWithUndefined();
return;
}
ipcPromise->Then(
NS_GetCurrentThread(), __func__,
[promise = RefPtr<dom::Promise>(promise), aOnlyTheFirstMatch](
const CookieStoreChild::GetRequestPromise::ResolveOrRejectValue&
aResult) {
nsTArray<CookieListItem> list;
MOZ_ASSERT(aResult.IsResolve());
CookieDataToList(aResult.ResolveValue(), list);
if (!aOnlyTheFirstMatch) {
promise->MaybeResolve(list);
return;
}
if (list.IsEmpty()) {
promise->MaybeResolve(JS::NullHandleValue);
return;
}
promise->MaybeResolve(list[0]);
});
}));
return promise.forget();
}
void CookieStore::FireDelayedDOMEvents() {
MOZ_ASSERT(NS_IsMainThread());
if (mNotifier) {
mNotifier->FireDelayedDOMEvents();
}
}
Document* CookieStore::MaybeGetDocument() const {
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = GetOwnerWindow();
MOZ_ASSERT(window);
return window->GetExtantDoc();
}
return nullptr;
}
} // namespace mozilla::dom

View File

@ -1,81 +0,0 @@
/* -*- 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_dom_CookieStore_h
#define mozilla_dom_CookieStore_h
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/CookieStoreBinding.h"
class nsIGlobalObject;
namespace mozilla::dom {
class CookieData;
class CookieStoreChild;
class CookieStoreNotificationWatcherWrapper;
class CookieStoreNotifier;
class Promise;
class CookieStore final : public DOMEventTargetHelper {
friend class CookieStoreChild;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CookieStore, DOMEventTargetHelper)
static already_AddRefed<CookieStore> Create(nsIGlobalObject* aGlobalObject);
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
void FireDelayedDOMEvents();
already_AddRefed<Promise> Get(const nsAString& aName, ErrorResult& aRv);
already_AddRefed<Promise> Get(const CookieStoreGetOptions& aOptions,
ErrorResult& aRv);
already_AddRefed<Promise> GetAll(const nsAString& aName, ErrorResult& aRv);
already_AddRefed<Promise> GetAll(const CookieStoreGetOptions& aOptions,
ErrorResult& aRv);
already_AddRefed<Promise> Set(const nsAString& aName, const nsAString& aValue,
ErrorResult& aRv);
already_AddRefed<Promise> Set(const CookieInit& aOptions, ErrorResult& aRv);
already_AddRefed<Promise> Delete(const nsAString& aName, ErrorResult& aRv);
already_AddRefed<Promise> Delete(const CookieStoreDeleteOptions& aOptions,
ErrorResult& aRv);
IMPL_EVENT_HANDLER(change);
private:
explicit CookieStore(nsIGlobalObject* aGlobal);
~CookieStore();
void Shutdown();
Document* MaybeGetDocument() const;
already_AddRefed<Promise> GetInternal(const CookieStoreGetOptions& aOptions,
bool aOnlyTheFirstMatch,
ErrorResult& aRv);
bool MaybeCreateActor();
RefPtr<CookieStoreChild> mActor;
RefPtr<CookieStoreNotifier> mNotifier;
RefPtr<CookieStoreNotificationWatcherWrapper> mNotificationWatcher;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_CookieStore_h */

View File

@ -1,28 +0,0 @@
/* -*- 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 "CookieStore.h"
#include "CookieStoreChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
namespace mozilla {
using namespace ipc;
namespace dom {
CookieStoreChild::CookieStoreChild() = default;
CookieStoreChild::~CookieStoreChild() = default;
void CookieStoreChild::Close() {
if (CanSend()) {
SendClose();
}
}
} // namespace dom
} // namespace mozilla

View File

@ -1,31 +0,0 @@
/* -*- 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_dom_CookieStoreChild_h
#define mozilla_dom_CookieStoreChild_h
#include "mozilla/dom/PCookieStoreChild.h"
#include "nsISupportsImpl.h"
namespace mozilla::dom {
class CookieStoreChild final : public PCookieStoreChild {
friend class PCookieStoreChild;
public:
NS_INLINE_DECL_REFCOUNTING(CookieStoreChild)
CookieStoreChild();
void Close();
private:
~CookieStoreChild();
};
} // namespace mozilla::dom
#endif // mozilla_dom_CookieStoreChild_h

View File

@ -1,129 +0,0 @@
/* -*- 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 "CookieStoreNotificationWatcher.h"
#include "mozilla/Services.h"
#include "mozilla/Unused.h"
#include "nsICookie.h"
#include "nsICookieNotification.h"
#include "nsIObserverService.h"
namespace mozilla::dom {
NS_IMPL_ISUPPORTS(CookieStoreNotificationWatcher, nsIObserver,
nsISupportsWeakReference)
// static
already_AddRefed<CookieStoreNotificationWatcher>
CookieStoreNotificationWatcher::Create(bool aPrivateBrowsing) {
MOZ_ASSERT(NS_IsMainThread());
RefPtr<CookieStoreNotificationWatcher> watcher =
new CookieStoreNotificationWatcher();
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (NS_WARN_IF(!os)) {
return nullptr;
}
nsresult rv = os->AddObserver(
watcher, aPrivateBrowsing ? "private-cookie-changed" : "cookie-changed",
true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return watcher.forget();
}
NS_IMETHODIMP
CookieStoreNotificationWatcher::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsICookieNotification> notification = do_QueryInterface(aSubject);
NS_ENSURE_TRUE(notification, NS_ERROR_FAILURE);
nsID* operationID = nullptr;
nsresult rv = notification->GetOperationID(&operationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_OK;
}
if (!operationID) {
return NS_OK;
}
for (uint32_t i = 0; i < mPendingOperations.Length(); ++i) {
PendingOperation& pendingOperation = mPendingOperations[i];
if (pendingOperation.mOperationID.Equals(*operationID)) {
pendingOperation.mCallback();
mPendingOperations.RemoveElementAt(i);
break;
}
}
return NS_OK;
}
void CookieStoreNotificationWatcher::CallbackWhenNotified(
const nsID& aOperationID, MoveOnlyFunction<void()> aCallback) {
MOZ_ASSERT(NS_IsMainThread());
mPendingOperations.AppendElement(
PendingOperation{std::move(aCallback), aOperationID});
}
void CookieStoreNotificationWatcher::ForgetOperationID(
const nsID& aOperationID) {
MOZ_ASSERT(NS_IsMainThread());
for (uint32_t i = 0; i < mPendingOperations.Length(); ++i) {
PendingOperation& pendingOperation = mPendingOperations[i];
if (pendingOperation.mOperationID.Equals(aOperationID)) {
mPendingOperations.RemoveElementAt(i);
return;
}
}
}
// static
void CookieStoreNotificationWatcher::ReleaseOnMainThread(
already_AddRefed<CookieStoreNotificationWatcher> aWatcher) {
RefPtr<CookieStoreNotificationWatcher> watcher(aWatcher);
if (!watcher || NS_IsMainThread()) {
return;
}
class ReleaseWatcher final : public Runnable {
public:
explicit ReleaseWatcher(
already_AddRefed<CookieStoreNotificationWatcher> aWatcher)
: Runnable("ReleaseWatcher"), mDoomed(std::move(aWatcher)) {}
NS_IMETHOD Run() override {
mDoomed = nullptr;
return NS_OK;
}
private:
~ReleaseWatcher() {
// If we still have to release the watcher, better to leak it.
if (mDoomed) {
Unused << mDoomed.forget().take();
}
}
RefPtr<CookieStoreNotificationWatcher> mDoomed;
};
RefPtr<ReleaseWatcher> runnable(new ReleaseWatcher(watcher.forget()));
NS_DispatchToMainThread(runnable);
}
} // namespace mozilla::dom

View File

@ -1,51 +0,0 @@
/* -*- 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_dom_CookieStoreNotificationWatcher_h
#define mozilla_dom_CookieStoreNotificationWatcher_h
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "mozilla/OriginAttributes.h"
#include "mozilla/MoveOnlyFunction.h"
namespace mozilla::dom {
class CookieStoreNotificationWatcher final : public nsIObserver,
public nsSupportsWeakReference {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static already_AddRefed<CookieStoreNotificationWatcher> Create(
bool aPrivateBrowsing);
static void ReleaseOnMainThread(
already_AddRefed<CookieStoreNotificationWatcher> aWatcher);
void CallbackWhenNotified(const nsID& aOperationID,
MoveOnlyFunction<void()> aCallback);
void ForgetOperationID(const nsID& aOperationID);
private:
CookieStoreNotificationWatcher() = default;
~CookieStoreNotificationWatcher() = default;
void MaybeResolveOperations(const nsID* aOperationID);
struct PendingOperation {
MoveOnlyFunction<void()> mCallback;
nsID mOperationID;
};
// This is a simple list because I don't think we will have so many concurrent
// operations to motivate an hash table.
nsTArray<PendingOperation> mPendingOperations;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_CookieStoreNotificationWatcher_h */

View File

@ -1,158 +0,0 @@
/* -*- 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 "CookieStoreNotificationWatcherWrapper.h"
#include "CookieStoreNotificationWatcher.h"
#include "CookieStore.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/dom/WorkerRef.h"
#include "nsProxyRelease.h"
namespace mozilla::dom {
// static
already_AddRefed<CookieStoreNotificationWatcherWrapper>
CookieStoreNotificationWatcherWrapper::Create(CookieStore* aCookieStore) {
MOZ_ASSERT(aCookieStore);
nsIPrincipal* principal = nullptr;
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
principal = workerPrivate->GetPrincipal();
} else {
nsCOMPtr<nsPIDOMWindowInner> window = aCookieStore->GetOwnerWindow();
MOZ_ASSERT(window);
nsCOMPtr<Document> document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) {
return nullptr;
}
principal = document->NodePrincipal();
}
if (NS_WARN_IF(!principal)) {
return nullptr;
}
RefPtr<CookieStoreNotificationWatcherWrapper> wrapper =
new CookieStoreNotificationWatcherWrapper();
bool privateBrowsing = principal->OriginAttributesRef().IsPrivateBrowsing();
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(
NS_NewRunnableFunction(__func__, [wrapper, privateBrowsing] {
wrapper->CreateWatcherOnMainThread(privateBrowsing);
}));
} else {
wrapper->CreateWatcherOnMainThread(privateBrowsing);
}
return wrapper.forget();
}
CookieStoreNotificationWatcherWrapper::
~CookieStoreNotificationWatcherWrapper() {
CookieStoreNotificationWatcher::ReleaseOnMainThread(
mWatcherOnMainThread.forget());
}
void CookieStoreNotificationWatcherWrapper::CreateWatcherOnMainThread(
bool aPrivateBrowsing) {
MOZ_ASSERT(NS_IsMainThread());
mWatcherOnMainThread =
CookieStoreNotificationWatcher::Create(aPrivateBrowsing);
}
void CookieStoreNotificationWatcherWrapper::ForgetOperationID(
const nsID& aOperationID) {
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(
NS_NewRunnableFunction(__func__, [self = RefPtr(this), aOperationID] {
self->ForgetOperationID(aOperationID);
}));
return;
}
if (mWatcherOnMainThread) {
mWatcherOnMainThread->ForgetOperationID(aOperationID);
}
}
void CookieStoreNotificationWatcherWrapper::ResolvePromiseWhenNotified(
const nsID& aOperationID, Promise* aPromise) {
MOZ_ASSERT(aPromise);
class PromiseResolver final : public Runnable {
public:
explicit PromiseResolver(Promise* aPromise)
: Runnable("CookieStoreNotificationWatcherWrapper::PromiseResolver"),
mPromise(aPromise),
mEventTarget(GetCurrentSerialEventTarget()) {}
NS_IMETHOD Run() override {
mPromise->MaybeResolveWithUndefined();
mPromise = nullptr;
return NS_OK;
}
bool HasPromise() const { return !!mPromise; }
private:
~PromiseResolver() {
NS_ProxyRelease(
"CookieStoreNotificationWatcherWrapper::PromiseResolver::mPromise",
mEventTarget, mPromise.forget());
}
RefPtr<Promise> mPromise;
RefPtr<nsISerialEventTarget> mEventTarget;
};
RefPtr<PromiseResolver> resolver(new PromiseResolver(aPromise));
RefPtr<ThreadSafeWorkerRef> workerRef;
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
RefPtr<StrongWorkerRef> strongWorkerRef = StrongWorkerRef::Create(
workerPrivate, "CookieStoreNotificationWatcher::PromiseResolver",
[resolver = RefPtr(resolver)]() { resolver->Run(); });
workerRef = new ThreadSafeWorkerRef(strongWorkerRef);
}
auto callback = [resolver = RefPtr(resolver),
eventTarget = RefPtr(GetCurrentSerialEventTarget()),
workerRef = RefPtr(workerRef)] {
if (resolver->HasPromise()) {
RefPtr<Runnable> runnable(resolver);
eventTarget->Dispatch(runnable.forget());
}
};
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(NS_NewRunnableFunction(
__func__, [self = RefPtr(this), callback, aOperationID] {
self->mWatcherOnMainThread->CallbackWhenNotified(aOperationID,
callback);
}));
return;
}
if (mWatcherOnMainThread) {
mWatcherOnMainThread->CallbackWhenNotified(aOperationID, callback);
}
}
} // namespace mozilla::dom

View File

@ -1,39 +0,0 @@
/* -*- 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_dom_CookieStoreNotificationWatcherWrapper_h
#define mozilla_dom_CookieStoreNotificationWatcherWrapper_h
#include "mozilla/OriginAttributes.h"
namespace mozilla::dom {
class Promise;
class CookieStore;
class CookieStoreNotificationWatcher;
class CookieStoreNotificationWatcherWrapper final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CookieStoreNotificationWatcherWrapper)
static already_AddRefed<CookieStoreNotificationWatcherWrapper> Create(
CookieStore* aCookieStore);
void ResolvePromiseWhenNotified(const nsID& aOperationID, Promise* aPromise);
void ForgetOperationID(const nsID& aOperationID);
private:
CookieStoreNotificationWatcherWrapper() = default;
~CookieStoreNotificationWatcherWrapper();
void CreateWatcherOnMainThread(bool aPrivateBrowsing);
RefPtr<CookieStoreNotificationWatcher> mWatcherOnMainThread;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_CookieStoreNotificationWatcherWrapper_h */

View File

@ -1,256 +0,0 @@
/* -*- 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 "CookieStoreNotifier.h"
#include "CookieStore.h"
#include "CookieChangeEvent.h"
#include "mozilla/net/CookieCommons.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/Unused.h"
#include "nsICookie.h"
#include "nsICookieNotification.h"
#include "nsISerialEventTarget.h"
namespace mozilla::dom {
NS_IMPL_ISUPPORTS(CookieStoreNotifier, nsIObserver);
// static
already_AddRefed<CookieStoreNotifier> CookieStoreNotifier::Create(
CookieStore* aCookieStore) {
nsIPrincipal* principal = nullptr;
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
principal = workerPrivate->GetPrincipal();
} else {
nsCOMPtr<nsPIDOMWindowInner> window = aCookieStore->GetOwnerWindow();
MOZ_ASSERT(window);
nsCOMPtr<Document> document = window->GetExtantDoc();
if (NS_WARN_IF(!document)) {
return nullptr;
}
principal = document->NodePrincipal();
}
if (NS_WARN_IF(!principal)) {
return nullptr;
}
nsCString baseDomain;
if (NS_WARN_IF(NS_FAILED(
net::CookieCommons::GetBaseDomain(principal, baseDomain)))) {
return nullptr;
}
if (baseDomain.IsEmpty()) {
return nullptr;
}
RefPtr<CookieStoreNotifier> notifier = new CookieStoreNotifier(
aCookieStore, baseDomain, principal->OriginAttributesRef());
bool privateBrowsing = principal->OriginAttributesRef().IsPrivateBrowsing();
notifier->mEventTarget = GetCurrentSerialEventTarget();
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(
NS_NewRunnableFunction(__func__, [notifier, privateBrowsing] {
notifier->AddObserversOnMainThread(privateBrowsing);
}));
} else {
notifier->AddObserversOnMainThread(privateBrowsing);
}
return notifier.forget();
}
CookieStoreNotifier::CookieStoreNotifier(
CookieStore* aCookieStore, const nsACString& aBaseDomain,
const OriginAttributes& aOriginAttributes)
: mCookieStore(aCookieStore),
mBaseDomain(aBaseDomain),
mOriginAttributes(aOriginAttributes) {
MOZ_ASSERT(aCookieStore);
}
CookieStoreNotifier::~CookieStoreNotifier() = default;
void CookieStoreNotifier::Disentangle() {
mCookieStore = nullptr;
bool privateBrowsing = mOriginAttributes.IsPrivateBrowsing();
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(NS_NewRunnableFunction(
__func__, [self = RefPtr(this), privateBrowsing] {
self->RemoveObserversOnMainThread(privateBrowsing);
}));
} else {
RemoveObserversOnMainThread(privateBrowsing);
}
}
void CookieStoreNotifier::AddObserversOnMainThread(bool aPrivateBrowsing) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (NS_WARN_IF(!os)) {
return;
}
nsresult rv = os->AddObserver(
this, aPrivateBrowsing ? "private-cookie-changed" : "cookie-changed",
false);
Unused << NS_WARN_IF(NS_FAILED(rv));
}
void CookieStoreNotifier::RemoveObserversOnMainThread(bool aPrivateBrowsing) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (NS_WARN_IF(!os)) {
return;
}
nsresult rv = os->RemoveObserver(
this, aPrivateBrowsing ? "private-cookie-changed" : "cookie-changed");
Unused << NS_WARN_IF(NS_FAILED(rv));
}
NS_IMETHODIMP
CookieStoreNotifier::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsICookieNotification> notification = do_QueryInterface(aSubject);
NS_ENSURE_TRUE(notification, NS_ERROR_FAILURE);
auto action = notification->GetAction();
if (action != nsICookieNotification::COOKIE_DELETED &&
action != nsICookieNotification::COOKIE_ADDED &&
action != nsICookieNotification::COOKIE_CHANGED) {
return NS_OK;
}
nsAutoCString baseDomain;
nsresult rv = notification->GetBaseDomain(baseDomain);
if (NS_WARN_IF(NS_FAILED(rv)) || baseDomain.IsEmpty()) {
return rv;
}
if (baseDomain != mBaseDomain) {
return NS_OK;
}
nsCOMPtr<nsICookie> cookie;
rv = notification->GetCookie(getter_AddRefs(cookie));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (cookie->OriginAttributesNative() != mOriginAttributes) {
return NS_OK;
}
bool isHttpOnly;
rv = cookie->GetIsHttpOnly(&isHttpOnly);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isHttpOnly) {
return NS_OK;
}
CookieListItem item;
nsAutoCString name;
rv = cookie->GetName(name);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
item.mName.Construct(NS_ConvertUTF8toUTF16(name));
if (action != nsICookieNotification::COOKIE_DELETED) {
nsAutoCString value;
rv = cookie->GetValue(value);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
item.mValue.Construct(NS_ConvertUTF8toUTF16(value));
}
bool deletedEvent = action == nsICookieNotification::COOKIE_DELETED;
if (mEventTarget->IsOnCurrentThread()) {
DispatchEvent(item, deletedEvent);
} else {
mEventTarget->Dispatch(NS_NewRunnableFunction(
__func__, [self = RefPtr(this), item, deletedEvent] {
self->DispatchEvent(item, deletedEvent);
}));
}
return NS_OK;
}
void CookieStoreNotifier::DispatchEvent(const CookieListItem& aItem,
bool aDeletedEvent) {
MOZ_ASSERT(mEventTarget->IsOnCurrentThread());
if (!mCookieStore) {
return;
}
RefPtr<Event> event =
aDeletedEvent
? CookieChangeEvent::CreateForDeletedCookie(mCookieStore, aItem)
: CookieChangeEvent::CreateForChangedCookie(mCookieStore, aItem);
if (!event) {
return;
}
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindowInner> window = mCookieStore->GetOwnerWindow();
if (!window) {
return;
}
RefPtr<BrowsingContext> bc = window->GetBrowsingContext();
if (!bc) {
return;
}
if (bc->IsInBFCache()) {
mDelayedDOMEvents.AppendElement(event);
return;
}
}
mCookieStore->DispatchEvent(*event);
}
void CookieStoreNotifier::FireDelayedDOMEvents() {
MOZ_ASSERT(NS_IsMainThread());
nsTArray<RefPtr<Event>> delayedDOMEvents;
delayedDOMEvents.SwapElements(mDelayedDOMEvents);
for (Event* event : delayedDOMEvents) {
mCookieStore->DispatchEvent(*event);
}
}
} // namespace mozilla::dom

View File

@ -1,57 +0,0 @@
/* -*- 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_dom_CookieStoreNotifier_h
#define mozilla_dom_CookieStoreNotifier_h
#include "nsIObserver.h"
#include "mozilla/OriginAttributes.h"
#include "mozilla/MoveOnlyFunction.h"
class nsISerialEventTarget;
namespace mozilla::dom {
class CookieStore;
struct CookieListItem;
class Event;
class CookieStoreNotifier final : public nsIObserver {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
static already_AddRefed<CookieStoreNotifier> Create(
CookieStore* aCookieStore);
void Disentangle();
void FireDelayedDOMEvents();
private:
CookieStoreNotifier(CookieStore* aCookieStore, const nsACString& aBaseDomain,
const OriginAttributes& aOriginAttributes);
~CookieStoreNotifier();
void AddObserversOnMainThread(bool aPrivateBrowsing);
void RemoveObserversOnMainThread(bool aPrivateBrowsing);
void DispatchEvent(const CookieListItem& aItem, bool aDeletedEvent);
// Raw pointer because this object is kept alive by this CookieStore object.
CookieStore* mCookieStore;
nsCString mBaseDomain;
OriginAttributes mOriginAttributes;
RefPtr<nsISerialEventTarget> mEventTarget;
nsTArray<RefPtr<Event>> mDelayedDOMEvents;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_CookieStoreNotifier_h */

View File

@ -1,412 +0,0 @@
/* -*- 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 "CookieStoreParent.h"
#include "CookieStoreNotificationWatcher.h"
#include "mozilla/Maybe.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/net/Cookie.h"
#include "mozilla/net/CookieCommons.h"
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/Unused.h"
#include "nsICookieManager.h"
#include "nsICookieService.h"
#include "nsProxyRelease.h"
using namespace mozilla::ipc;
using namespace mozilla::net;
namespace mozilla::dom {
namespace {
bool CheckContentProcessSecurity(ThreadsafeContentParentHandle* aParent,
const nsACString& aDomain,
const OriginAttributes& aOriginAttributes) {
AssertIsOnMainThread();
// ContentParent is null if we are dealing with the same process.
if (!aParent) {
return true;
}
RefPtr<ContentParent> contentParent = aParent->GetContentParent();
if (!contentParent) {
return true;
}
PNeckoParent* neckoParent =
LoneManagedOrNullAsserts(contentParent->ManagedPNeckoParent());
if (!neckoParent) {
return true;
}
PCookieServiceParent* csParent =
LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
if (!csParent) {
return true;
}
auto* cs = static_cast<CookieServiceParent*>(csParent);
return cs->ContentProcessHasCookie(aDomain, aOriginAttributes);
}
} // namespace
CookieStoreParent::CookieStoreParent() { AssertIsOnBackgroundThread(); }
CookieStoreParent::~CookieStoreParent() {
AssertIsOnBackgroundThread();
CookieStoreNotificationWatcher::ReleaseOnMainThread(
mNotificationWatcherOnMainThread.forget());
}
mozilla::ipc::IPCResult CookieStoreParent::RecvGetRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const Maybe<OriginAttributes>& aPartitionedOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const bool& aMatchName,
const nsString& aName, const nsCString& aPath, const bool& aOnlyFirstMatch,
GetRequestResolver&& aResolver) {
AssertIsOnBackgroundThread();
InvokeAsync(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr(this), aDomain, aOriginAttributes,
aPartitionedOriginAttributes, aThirdPartyContext, aPartitionForeign,
aUsingStorageAccess, aMatchName, aName, aPath, aOnlyFirstMatch]() {
CopyableTArray<CookieData> results;
self->GetRequestOnMainThread(
aDomain, aOriginAttributes, aPartitionedOriginAttributes,
aThirdPartyContext, aPartitionForeign, aUsingStorageAccess,
aMatchName, aName, aPath, aOnlyFirstMatch, results);
return GetRequestPromise::CreateAndResolve(std::move(results),
__func__);
})
->Then(GetCurrentSerialEventTarget(), __func__,
[aResolver = std::move(aResolver)](
const GetRequestPromise::ResolveOrRejectValue& aResult) {
MOZ_ASSERT(aResult.IsResolve());
aResolver(aResult.ResolveValue());
});
return IPC_OK();
}
mozilla::ipc::IPCResult CookieStoreParent::RecvSetRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const nsString& aName,
const nsString& aValue, const bool& aSession, const int64_t& aExpires,
const nsString& aPath, const int32_t& aSameSite, const bool& aPartitioned,
const nsID& aOperationID, SetRequestResolver&& aResolver) {
AssertIsOnBackgroundThread();
RefPtr<ThreadsafeContentParentHandle> parent =
BackgroundParent::GetContentParentHandle(Manager());
InvokeAsync(GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr(this), parent = RefPtr(parent), aDomain,
aOriginAttributes, aThirdPartyContext, aPartitionForeign,
aUsingStorageAccess, aName, aValue, aSession, aExpires, aPath,
aSameSite, aPartitioned, aOperationID]() {
bool waitForNotification = self->SetRequestOnMainThread(
parent, aDomain, aOriginAttributes, aThirdPartyContext,
aPartitionForeign, aUsingStorageAccess, aName, aValue,
aSession, aExpires, aPath, aSameSite, aPartitioned,
aOperationID);
return SetDeleteRequestPromise::CreateAndResolve(
waitForNotification, __func__);
})
->Then(GetCurrentSerialEventTarget(), __func__,
[aResolver = std::move(aResolver)](
const SetDeleteRequestPromise::ResolveOrRejectValue& aResult) {
MOZ_ASSERT(aResult.IsResolve());
aResolver(aResult.ResolveValue());
});
return IPC_OK();
}
mozilla::ipc::IPCResult CookieStoreParent::RecvDeleteRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const nsString& aName,
const nsString& aPath, const bool& aPartitioned, const nsID& aOperationID,
DeleteRequestResolver&& aResolver) {
AssertIsOnBackgroundThread();
RefPtr<ThreadsafeContentParentHandle> parent =
BackgroundParent::GetContentParentHandle(Manager());
InvokeAsync(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr(this), parent = RefPtr(parent), aDomain, aOriginAttributes,
aThirdPartyContext, aPartitionForeign, aUsingStorageAccess, aName, aPath,
aPartitioned, aOperationID]() {
bool waitForNotification = self->DeleteRequestOnMainThread(
parent, aDomain, aOriginAttributes, aThirdPartyContext,
aPartitionForeign, aUsingStorageAccess, aName, aPath, aPartitioned,
aOperationID);
return SetDeleteRequestPromise::CreateAndResolve(waitForNotification,
__func__);
})
->Then(GetCurrentSerialEventTarget(), __func__,
[aResolver = std::move(aResolver)](
const SetDeleteRequestPromise::ResolveOrRejectValue& aResult) {
MOZ_ASSERT(aResult.IsResolve());
aResolver(aResult.ResolveValue());
});
return IPC_OK();
}
mozilla::ipc::IPCResult CookieStoreParent::RecvClose() {
AssertIsOnBackgroundThread();
Unused << Send__delete__(this);
return IPC_OK();
}
void CookieStoreParent::GetRequestOnMainThread(
const nsAString& aDomain, const OriginAttributes& aOriginAttributes,
const Maybe<OriginAttributes>& aPartitionedOriginAttributes,
bool aThirdPartyContext, bool aPartitionForeign, bool aUsingStorageAccess,
bool aMatchName, const nsAString& aName, const nsACString& aPath,
bool aOnlyFirstMatch, nsTArray<CookieData>& aResults) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsICookieService> service =
do_GetService(NS_COOKIESERVICE_CONTRACTID);
if (!service) {
return;
}
NS_ConvertUTF16toUTF8 matchName(aName);
nsTArray<OriginAttributes> attrsList;
attrsList.AppendElement(aOriginAttributes);
if (aPartitionedOriginAttributes) {
attrsList.AppendElement(aPartitionedOriginAttributes.value());
}
nsTArray<CookieData> list;
for (const OriginAttributes& attrs : attrsList) {
nsTArray<RefPtr<Cookie>> cookies;
service->GetCookiesFromHost(NS_ConvertUTF16toUTF8(aDomain), attrs, cookies);
for (Cookie* cookie : cookies) {
if (cookie->IsHttpOnly()) {
continue;
}
if (aThirdPartyContext &&
!CookieCommons::ShouldIncludeCrossSiteCookie(
cookie, aPartitionForeign, attrs.IsPrivateBrowsing(),
aUsingStorageAccess)) {
continue;
}
if (aMatchName && !matchName.Equals(cookie->Name())) {
continue;
}
if (!net::CookieCommons::PathMatches(cookie->Path(), aPath)) {
continue;
}
CookieData* data = list.AppendElement();
data->name() = NS_ConvertUTF8toUTF16(cookie->Name());
data->value() = NS_ConvertUTF8toUTF16(cookie->Value());
if (aOnlyFirstMatch) {
break;
}
}
if (!list.IsEmpty() && aOnlyFirstMatch) {
break;
}
}
aResults.SwapElements(list);
}
bool CookieStoreParent::SetRequestOnMainThread(
ThreadsafeContentParentHandle* aParent, const nsAString& aDomain,
const OriginAttributes& aOriginAttributes, bool aThirdPartyContext,
bool aPartitionForeign, bool aUsingStorageAccess, const nsAString& aName,
const nsAString& aValue, bool aSession, int64_t aExpires,
const nsAString& aPath, int32_t aSameSite, bool aPartitioned,
const nsID& aOperationID) {
MOZ_ASSERT(NS_IsMainThread());
NS_ConvertUTF16toUTF8 domain(aDomain);
if (!CheckContentProcessSecurity(aParent, domain, aOriginAttributes)) {
return false;
}
if (aThirdPartyContext &&
!CookieCommons::ShouldIncludeCrossSiteCookie(
aSameSite, aPartitioned && !aOriginAttributes.mPartitionKey.IsEmpty(),
aPartitionForeign, aOriginAttributes.IsPrivateBrowsing(),
aUsingStorageAccess)) {
return false;
}
nsCOMPtr<nsICookieManager> service =
do_GetService(NS_COOKIEMANAGER_CONTRACTID);
if (!service) {
return false;
}
bool notified = false;
auto notificationCb = [&]() { notified = true; };
CookieStoreNotificationWatcher* notificationWatcher =
GetOrCreateNotificationWatcherOnMainThread(aOriginAttributes);
if (!notificationWatcher) {
return false;
}
notificationWatcher->CallbackWhenNotified(aOperationID, notificationCb);
OriginAttributes attrs(aOriginAttributes);
nsresult rv = service->AddNative(
domain, NS_ConvertUTF16toUTF8(aPath), NS_ConvertUTF16toUTF8(aName),
NS_ConvertUTF16toUTF8(aValue),
true, // secure
false, // mHttpOnly,
aSession, aSession ? PR_Now() : aExpires, &attrs, aSameSite,
nsICookie::SCHEME_HTTPS, aPartitioned, &aOperationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
notificationWatcher->ForgetOperationID(aOperationID);
return notified;
}
bool CookieStoreParent::DeleteRequestOnMainThread(
ThreadsafeContentParentHandle* aParent, const nsAString& aDomain,
const OriginAttributes& aOriginAttributes, bool aThirdPartyContext,
bool aPartitionForeign, bool aUsingStorageAccess, const nsAString& aName,
const nsAString& aPath, bool aPartitioned, const nsID& aOperationID) {
MOZ_ASSERT(NS_IsMainThread());
NS_ConvertUTF16toUTF8 domain(aDomain);
if (!CheckContentProcessSecurity(aParent, domain, aOriginAttributes)) {
return false;
}
nsCOMPtr<nsICookieManager> service =
do_GetService(NS_COOKIEMANAGER_CONTRACTID);
if (!service) {
return false;
}
OriginAttributes attrs(aOriginAttributes);
nsTArray<RefPtr<nsICookie>> results;
nsresult rv = service->GetCookiesFromHostNative(domain, &attrs, results);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
NS_ConvertUTF16toUTF8 matchName(aName);
NS_ConvertUTF16toUTF8 matchPath(aPath);
for (nsICookie* cookie : results) {
MOZ_ASSERT(cookie);
nsAutoCString name;
rv = cookie->GetName(name);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!matchName.Equals(name)) {
continue;
}
nsAutoCString path;
rv = cookie->GetPath(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!matchPath.IsEmpty() && !matchPath.Equals(path)) {
continue;
}
bool isPartitioned = false;
rv = cookie->GetIsPartitioned(&isPartitioned);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (isPartitioned != aPartitioned) continue;
if (aThirdPartyContext) {
int32_t sameSiteAttr = 0;
rv = cookie->GetSameSite(&sameSiteAttr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
if (!CookieCommons::ShouldIncludeCrossSiteCookie(
sameSiteAttr,
isPartitioned && !aOriginAttributes.mPartitionKey.IsEmpty(),
aPartitionForeign, attrs.IsPrivateBrowsing(),
aUsingStorageAccess)) {
return false;
}
}
bool notified = false;
auto notificationCb = [&]() { notified = true; };
CookieStoreNotificationWatcher* notificationWatcher =
GetOrCreateNotificationWatcherOnMainThread(aOriginAttributes);
if (!notificationWatcher) {
return false;
}
notificationWatcher->CallbackWhenNotified(aOperationID, notificationCb);
rv = service->RemoveNative(domain, matchName, path, &attrs, &aOperationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
notificationWatcher->ForgetOperationID(aOperationID);
return notified;
}
return false;
}
CookieStoreNotificationWatcher*
CookieStoreParent::GetOrCreateNotificationWatcherOnMainThread(
const OriginAttributes& aOriginAttributes) {
MOZ_ASSERT(NS_IsMainThread());
if (!mNotificationWatcherOnMainThread) {
mNotificationWatcherOnMainThread = CookieStoreNotificationWatcher::Create(
aOriginAttributes.IsPrivateBrowsing());
}
return mNotificationWatcherOnMainThread;
}
} // namespace mozilla::dom

View File

@ -1,93 +0,0 @@
/* -*- 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_dom_CookieStoreParent_h
#define mozilla_dom_CookieStoreParent_h
#include "mozilla/dom/PCookieStoreParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/MozPromise.h"
namespace mozilla::dom {
class CookieStoreNotificationWatcher;
class CookieStoreParent final : public PCookieStoreParent {
friend class PCookieStoreParent;
public:
using GetRequestPromise =
MozPromise<CopyableTArray<CookieData>, nsresult, true>;
using SetDeleteRequestPromise = MozPromise<bool, nsresult, true>;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CookieStoreParent)
CookieStoreParent();
private:
~CookieStoreParent();
mozilla::ipc::IPCResult RecvGetRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const Maybe<OriginAttributes>& aPartitionedOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const bool& aMatchName,
const nsString& aName, const nsCString& aPath,
const bool& aOnlyFirstMatch, GetRequestResolver&& aResolver);
mozilla::ipc::IPCResult RecvSetRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const nsString& aName,
const nsString& aValue, const bool& aSession, const int64_t& aExpires,
const nsString& aPath, const int32_t& aSameSite, const bool& aPartitioned,
const nsID& aOperationID, SetRequestResolver&& aResolver);
mozilla::ipc::IPCResult RecvDeleteRequest(
const nsString& aDomain, const OriginAttributes& aOriginAttributes,
const bool& aThirdPartyContext, const bool& aPartitionForeign,
const bool& aUsingStorageAccess, const nsString& aName,
const nsString& aPath, const bool& aPartitioned, const nsID& aOperationID,
DeleteRequestResolver&& aResolver);
mozilla::ipc::IPCResult RecvClose();
void GetRequestOnMainThread(
const nsAString& aDomain, const OriginAttributes& aOriginAttributes,
const Maybe<OriginAttributes>& aPartitionedOriginAttributes,
bool aThirdPartyContext, bool aPartitionForeign, bool aUsingStorageAccess,
bool aMatchName, const nsAString& aName, const nsACString& aPath,
bool aOnlyFirstMatch, nsTArray<CookieData>& aResults);
// Returns true if a cookie notification has been generated while completing
// the operation.
bool SetRequestOnMainThread(ThreadsafeContentParentHandle* aParent,
const nsAString& aDomain,
const OriginAttributes& aOriginAttributes,
bool aThirdPartyContext, bool aPartitionForeign,
bool aUsingStorageAccess, const nsAString& aName,
const nsAString& aValue, bool aSession,
int64_t aExpires, const nsAString& aPath,
int32_t aSameSite, bool aPartitioned,
const nsID& aOperationID);
// Returns true if a cookie notification has been generated while completing
// the operation.
bool DeleteRequestOnMainThread(
ThreadsafeContentParentHandle* aParent, const nsAString& aDomain,
const OriginAttributes& aOriginAttributes, bool aThirdPartyContext,
bool aPartitionForeign, bool aUsingStorageAccess, const nsAString& aName,
const nsAString& aPath, bool aPartitioned, const nsID& aOperationID);
CookieStoreNotificationWatcher* GetOrCreateNotificationWatcherOnMainThread(
const OriginAttributes& aOriginAttributes);
RefPtr<CookieStoreNotificationWatcher> mNotificationWatcherOnMainThread;
};
} // namespace mozilla::dom
#endif // mozilla_dom_CookieStoreParent_h

View File

@ -1,75 +0,0 @@
/* 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 protocol PBackground;
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
using struct nsID from "nsID.h";
namespace mozilla {
namespace dom {
struct CookieData
{
nsString name;
nsString value;
};
union MaybeCookieData
{
CookieData;
void_t;
};
// This protocol is used for the CookieStore API
[ManualDealloc]
protocol PCookieStore
{
manager PBackground;
parent:
async GetRequest(nsString domain,
OriginAttributes attrs,
OriginAttributes? partitionedAttrs,
bool thirdPartyContext,
bool partitionForeign,
bool usingStorageAccess,
bool matchName,
nsString name,
nsCString path,
bool onlyFirstMatch) returns (CookieData[] data);
async SetRequest(nsString domain,
OriginAttributes attrs,
bool thirdPartyContext,
bool partitionForeign,
bool usingStorageAccess,
nsString name,
nsString value,
bool session,
int64_t expires,
nsString path,
int32_t sameSite,
bool partitioned,
nsID operationId) returns (bool waitForNotification);
async DeleteRequest(nsString domain,
OriginAttributes attrs,
bool thirdPartyContext,
bool partitionForeign,
bool usingStorageAccess,
nsString name,
nsString path,
bool partitioned,
nsID operationID) returns (bool waitForNotification);
async Close();
child:
async __delete__();
};
} // namespace dom
} // namespace mozilla

View File

@ -1,36 +0,0 @@
# 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/.
with Files("**"):
BUG_COMPONENT = ("Core", "Networking: Cookies")
EXPORTS.mozilla.dom += [
"CookieChangeEvent.h",
"CookieStore.h",
"CookieStoreChild.h",
"CookieStoreParent.h",
]
UNIFIED_SOURCES += [
"CookieChangeEvent.cpp",
"CookieStore.cpp",
"CookieStoreChild.cpp",
"CookieStoreNotificationWatcher.cpp",
"CookieStoreNotificationWatcherWrapper.cpp",
"CookieStoreNotifier.cpp",
"CookieStoreParent.cpp",
]
LOCAL_INCLUDES += [
"../base",
"../events",
]
IPDL_SOURCES += [
"PCookieStore.ipdl",
]
include("/ipc/chromium/chromium-config.mozbuild")
FINAL_LIBRARY = "xul"

View File

@ -3845,8 +3845,6 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
auto* cs = static_cast<CookieServiceParent*>(csParent);
MOZ_ASSERT(mCookieInContentListCache.IsEmpty());
if (action == nsICookieNotification::COOKIES_BATCH_DELETED) {
nsCOMPtr<nsIArray> cookieList;
DebugOnly<nsresult> rv =
@ -3868,7 +3866,7 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
}
nsCOMPtr<nsICookie> xpcCookie;
nsresult rv = notification->GetCookie(getter_AddRefs(xpcCookie));
DebugOnly<nsresult> rv = notification->GetCookie(getter_AddRefs(xpcCookie));
NS_ASSERTION(NS_SUCCEEDED(rv) && xpcCookie, "couldn't get cookie");
// only broadcast the cookie change to content processes that need it
@ -3879,17 +3877,11 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
nsID* operationID = nullptr;
rv = notification->GetOperationID(&operationID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_OK;
}
if (action == nsICookieNotification::COOKIE_DELETED) {
cs->RemoveCookie(cookie, operationID);
cs->RemoveCookie(cookie);
} else if (action == nsICookieNotification::COOKIE_ADDED ||
action == nsICookieNotification::COOKIE_CHANGED) {
cs->AddCookie(cookie, operationID);
cs->AddCookie(cookie);
}
} else if (!strcmp(aTopic, NS_NETWORK_LINK_TYPE_TOPIC)) {
UpdateNetworkLinkType();
@ -6141,17 +6133,6 @@ nsresult ContentParent::TransmitPermissionsForPrincipal(
return NS_OK;
}
void ContentParent::AddPrincipalToCookieInProcessCache(
nsIPrincipal* aPrincipal) {
MOZ_ASSERT(aPrincipal);
mCookieInContentListCache.AppendElement(aPrincipal);
}
void ContentParent::TakeCookieInProcessCache(
nsTArray<nsCOMPtr<nsIPrincipal>>& aList) {
aList.SwapElements(mCookieInContentListCache);
}
void ContentParent::TransmitBlobURLsForPrincipal(nsIPrincipal* aPrincipal) {
// If we're already broadcasting BlobURLs with this principal, we don't need
// to send them here.

View File

@ -629,12 +629,6 @@ class ContentParent final : public PContentParent,
// to this content process forever.
void TransmitBlobURLsForPrincipal(nsIPrincipal* aPrincipal);
// Update a cache list of allowed domains to store cookies for the current
// process. This method is called when PCookieServiceParent actor is not
// available yet.
void AddPrincipalToCookieInProcessCache(nsIPrincipal* aPrincipal);
void TakeCookieInProcessCache(nsTArray<nsCOMPtr<nsIPrincipal>>& aList);
nsresult TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal);
// Whenever receiving a Principal we need to validate that Principal case
@ -1575,8 +1569,6 @@ class ContentParent final : public PContentParent,
nsTArray<nsCString> mBlobURLs;
nsTArray<nsCOMPtr<nsIPrincipal>> mCookieInContentListCache;
// This is intended to be a memory and time efficient means of determining
// whether an origin has ever existed in a process so that Blob URL broadcast
// doesn't need to transmit every Blob URL to every content process. False

View File

@ -37,7 +37,6 @@ DIRS += [
"chrome-webidl",
"clients",
"commandhandler",
"cookiestore",
"credentialmanagement",
"crypto",
"debugger",

View File

@ -1,27 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is:
* https://wicg.github.io/cookie-store/#CookieChangeEvent
*/
[Exposed=Window,
SecureContext,
Pref="dom.cookieStore.enabled"]
interface CookieChangeEvent : Event {
constructor(DOMString type, optional CookieChangeEventInit eventInitDict = {});
// TODO: Use FrozenArray once available. (Bug 1236777)
// [SameObject] readonly attribute FrozenArray<CookieListItem> changed;
// [SameObject] readonly attribute FrozenArray<CookieListItem> deleted;
[Frozen, Cached, Constant]
readonly attribute sequence<CookieListItem> changed;
[Frozen, Cached, Constant]
readonly attribute sequence<CookieListItem> deleted;
};
dictionary CookieChangeEventInit : EventInit {
CookieList changed;
CookieList deleted;
};

View File

@ -1,100 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*
* The origin of this IDL file is
* https://wicg.github.io/cookie-store/#idl-index
*
* Copyright © 2024 the Contributors to the Cookie Store API Specification,
* published by the Web Platform Incubator Community Group under the W3C
* Community Contributor License Agreement (CLA). A human-readable summary is
* available.
*/
[Exposed=(ServiceWorker,Window),
SecureContext,
Pref="dom.cookieStore.enabled"]
interface CookieStore : EventTarget {
[Throws]
Promise<CookieListItem?> get(USVString name);
[Throws]
Promise<CookieListItem?> get(optional CookieStoreGetOptions options = {});
[Throws]
Promise<CookieList> getAll(USVString name);
[Throws]
Promise<CookieList> getAll(optional CookieStoreGetOptions options = {});
[Throws]
Promise<undefined> set(USVString name, USVString value);
[Throws]
Promise<undefined> set(CookieInit options);
[Throws]
Promise<undefined> delete(USVString name);
[Throws]
Promise<undefined> delete(CookieStoreDeleteOptions options);
/* Bug 1475599 - By spec, `onchange` should be available only on `Window`,
* but because we do not want to implement the ExtendableCookieChangeEvent
* for ServiceWorker, we have decided to expose this EventHandler everywhere.
*/
//[Exposed=Window]
attribute EventHandler onchange;
};
dictionary CookieStoreGetOptions {
USVString name;
USVString url;
};
enum CookieSameSite {
"strict",
"lax",
"none"
};
dictionary CookieInit {
required USVString name;
required USVString value;
DOMHighResTimeStamp? expires = null;
USVString? domain = null;
USVString path = "/";
CookieSameSite sameSite = "strict";
boolean partitioned = false;
};
dictionary CookieStoreDeleteOptions {
required USVString name;
USVString? domain = null;
USVString path = "/";
boolean partitioned = false;
};
dictionary CookieListItem {
USVString name;
USVString value;
/* Bug 1475599 - We decide to do not implement the entire cookie-store spec.
* Instead, we implement only the subset that is compatible with document.cookie */
// USVString? domain;
// USVString path;
// DOMHighResTimeStamp? expires;
// boolean secure;
// CookieSameSite sameSite;
// boolean partitioned;
};
typedef sequence<CookieListItem> CookieList;
/* Bug 1475599 - We decide to do not implement the entire cookie-store spec.
* Instead, we implement only the subset that is compatible with document.cookie
[Exposed=(ServiceWorker,Window),
SecureContext]
interface CookieStoreManager {
Promise<undefined> subscribe(sequence<CookieStoreGetOptions> subscriptions);
Promise<sequence<CookieStoreGetOptions>> getSubscriptions();
Promise<undefined> unsubscribe(sequence<CookieStoreGetOptions> subscriptions);
};
*/

View File

@ -7,7 +7,6 @@
* http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html
* http://w3c.github.io/push-api/
* https://notifications.spec.whatwg.org/
* https://wicg.github.io/cookie-store/#ServiceWorkerGlobalScope
*
* You are granted a license to use, reproduce and create derivative works of
* this document.
@ -48,13 +47,3 @@ partial interface ServiceWorkerGlobalScope {
// Mixin the WebExtensions API globals (the actual properties are only available to
// extension service workers, locked behind a Func="extensions::ExtensionAPIAllowed" annotation).
ServiceWorkerGlobalScope includes ExtensionGlobalsMixin;
// https://wicg.github.io/cookie-store/#ServiceWorkerGlobalScope
partial interface ServiceWorkerGlobalScope {
[SameObject, Pref="dom.cookieStore.enabled"] readonly attribute CookieStore cookieStore;
/* Bug 1475599 - We decide to do not implement the entire cookie-store spec.
* Instead, we implement only the subset that is compatible with document.cookie
attribute EventHandler oncookiechange;
*/
};

View File

@ -7,7 +7,6 @@
* http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html
* https://w3c.github.io/push-api/
* https://notifications.spec.whatwg.org/
* https://wicg.github.io/cookie-store/#idl-index
*/
[Func="ServiceWorkerVisible",
@ -53,11 +52,3 @@ partial interface ServiceWorkerRegistration {
[NewObject, Func="mozilla::dom::Notification::PrefEnabled"]
Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter = {});
};
/* Bug 1475599 - We decide to do not implement the entire cookie-store spec.
* Instead, we implement only the subset that is compatible with document.cookie
[Exposed=(ServiceWorker,Window)]
partial interface ServiceWorkerRegistration {
[SameObject] readonly attribute CookieStoreManager cookies;
};
*/

View File

@ -17,7 +17,6 @@
* https://w3c.github.io/requestidlecallback/
* https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet
* https://wicg.github.io/visual-viewport/#the-visualviewport-interface
* https://wicg.github.io/cookie-store/#Window
*/
interface Principal;
@ -812,9 +811,3 @@ partial interface Window {
dictionary WindowPostMessageOptions : StructuredSerializeOptions {
USVString targetOrigin = "/";
};
// https://wicg.github.io/cookie-store/#Window
[SecureContext]
partial interface Window {
[SameObject, Pref="dom.cookieStore.enabled"] readonly attribute CookieStore cookieStore;
};

View File

@ -480,8 +480,6 @@ WEBIDL_FILES = [
"Console.webidl",
"ConstantSourceNode.webidl",
"ConvolverNode.webidl",
"CookieChangeEvent.webidl",
"CookieStore.webidl",
"CreateOfferRequest.webidl",
"CredentialManagement.webidl",
"Crypto.webidl",

View File

@ -48,7 +48,6 @@
#include "mozilla/dom/ClientSource.h"
#include "mozilla/dom/Clients.h"
#include "mozilla/dom/Console.h"
#include "mozilla/dom/CookieStore.h"
#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
#include "mozilla/dom/DebuggerNotification.h"
#include "mozilla/dom/DebuggerNotificationBinding.h"
@ -1100,8 +1099,7 @@ void SharedWorkerGlobalScope::Close() {
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
mClients, mExtensionBrowser, mRegistration,
mCookieStore)
mClients, mExtensionBrowser, mRegistration)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerGlobalScope)
NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
@ -1248,14 +1246,6 @@ ServiceWorkerGlobalScope::AcquireExtensionBrowser() {
return mExtensionBrowser.clonePtr();
}
already_AddRefed<CookieStore> ServiceWorkerGlobalScope::CookieStore() {
if (!mCookieStore) {
mCookieStore = CookieStore::Create(this);
}
return do_AddRef(mCookieStore);
}
bool WorkerDebuggerGlobalScope::WrapGlobalObject(
JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) {
AssertIsOnWorkerThread();

View File

@ -55,7 +55,6 @@ class ClientInfo;
class ClientSource;
class Clients;
class Console;
class CookieStore;
class Crypto;
class DOMString;
class DebuggerNotificationManager;
@ -483,8 +482,6 @@ class ServiceWorkerGlobalScope final : public WorkerGlobalScope {
void EventListenerAdded(nsAtom* aType) override;
already_AddRefed<mozilla::dom::CookieStore> CookieStore();
IMPL_EVENT_HANDLER(message)
IMPL_EVENT_HANDLER(messageerror)
@ -494,8 +491,6 @@ class ServiceWorkerGlobalScope final : public WorkerGlobalScope {
IMPL_EVENT_HANDLER(push)
IMPL_EVENT_HANDLER(pushsubscriptionchange)
IMPL_EVENT_HANDLER(cookiechange)
private:
~ServiceWorkerGlobalScope();
@ -505,7 +500,6 @@ class ServiceWorkerGlobalScope final : public WorkerGlobalScope {
const nsString mScope;
RefPtr<ServiceWorkerRegistration> mRegistration;
SafeRefPtr<extensions::ExtensionBrowser> mExtensionBrowser;
RefPtr<mozilla::dom::CookieStore> mCookieStore;
};
class WorkerDebuggerGlobalScope final : public WorkerGlobalScopeBase {

View File

@ -17,9 +17,6 @@
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundParent.h"
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/StaticPrefs_extensions.h"
#include "nsCOMPtr.h"
#include "nsImportModule.h"
@ -39,7 +36,6 @@ mozilla::LazyLogModule gRemoteWorkerManagerLog("RemoteWorkerManager");
namespace mozilla {
using namespace ipc;
using namespace net;
namespace dom {
@ -54,7 +50,7 @@ bool IsServiceWorker(const RemoteWorkerData& aData) {
OptionalServiceWorkerData::TServiceWorkerData;
}
void TransmitPermissionsAndCookiesAndBlobURLsForPrincipalInfo(
void TransmitPermissionsAndBlobURLsForPrincipalInfo(
ContentParent* aContentParent, const PrincipalInfo& aPrincipalInfo) {
AssertIsOnMainThread();
MOZ_ASSERT(aContentParent);
@ -71,25 +67,6 @@ void TransmitPermissionsAndCookiesAndBlobURLsForPrincipalInfo(
MOZ_ALWAYS_SUCCEEDS(
aContentParent->TransmitPermissionsForPrincipal(principal));
CookieServiceParent* cs = nullptr;
PNeckoParent* neckoParent =
LoneManagedOrNullAsserts(aContentParent->ManagedPNeckoParent());
if (neckoParent) {
PCookieServiceParent* csParent =
LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
if (csParent) {
cs = static_cast<CookieServiceParent*>(csParent);
}
}
if (cs) {
nsCOMPtr<nsIURI> uri = principal->GetURI();
cs->UpdateCookieInContentList(uri, principal->OriginAttributesRef());
} else {
aContentParent->AddPrincipalToCookieInProcessCache(principal);
}
}
} // namespace
@ -336,8 +313,8 @@ void RemoteWorkerManager::LaunchInternal(
AssertIsOnMainThread();
if (RefPtr<ContentParent> contentParent =
contentHandle->GetContentParent()) {
TransmitPermissionsAndCookiesAndBlobURLsForPrincipalInfo(
contentParent, principalInfo);
TransmitPermissionsAndBlobURLsForPrincipalInfo(contentParent,
principalInfo);
}
});

View File

@ -19,7 +19,6 @@
#include "mozilla/dom/PBackgroundLSRequestChild.h"
#include "mozilla/dom/PBackgroundLSSimpleRequestChild.h"
#include "mozilla/dom/PBackgroundSDBConnectionChild.h"
#include "mozilla/dom/CookieStoreChild.h"
#include "mozilla/dom/PFileSystemRequestChild.h"
#include "mozilla/dom/EndpointForReportChild.h"
#include "mozilla/dom/PVsync.h"
@ -321,26 +320,6 @@ bool BackgroundChildImpl::DeallocPBroadcastChannelChild(
return true;
}
// -----------------------------------------------------------------------------
// CookieStore API
// -----------------------------------------------------------------------------
dom::PCookieStoreChild* BackgroundChildImpl::AllocPCookieStoreChild() {
RefPtr<dom::CookieStoreChild> child = new dom::CookieStoreChild();
return child.forget().take();
}
bool BackgroundChildImpl::DeallocPCookieStoreChild(PCookieStoreChild* aActor) {
RefPtr<dom::CookieStoreChild> child =
dont_AddRef(static_cast<dom::CookieStoreChild*>(aActor));
MOZ_ASSERT(child);
return true;
}
// -----------------------------------------------------------------------------
// Camera API
// -----------------------------------------------------------------------------
camera::PCamerasChild* BackgroundChildImpl::AllocPCamerasChild() {
#ifdef MOZ_WEBRTC
RefPtr<camera::CamerasChild> agent = new camera::CamerasChild();

View File

@ -125,10 +125,6 @@ class BackgroundChildImpl : public PBackgroundChild {
virtual bool DeallocPBroadcastChannelChild(
PBroadcastChannelChild* aActor) override;
virtual PCookieStoreChild* AllocPCookieStoreChild() override;
virtual bool DeallocPCookieStoreChild(PCookieStoreChild* aActor) override;
virtual PServiceWorkerManagerChild* AllocPServiceWorkerManagerChild()
override;

View File

@ -18,7 +18,6 @@
#include "mozilla/dom/BackgroundSessionStorageServiceParent.h"
#include "mozilla/dom/ClientManagerActors.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/CookieStoreParent.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/EndpointForReportParent.h"
#include "mozilla/dom/FetchParent.h"
@ -822,27 +821,6 @@ bool BackgroundParentImpl::DeallocPBroadcastChannelParent(
return true;
}
mozilla::dom::PCookieStoreParent*
BackgroundParentImpl::AllocPCookieStoreParent() {
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
RefPtr<mozilla::dom::CookieStoreParent> actor =
new mozilla::dom::CookieStoreParent();
return actor.forget().take();
}
bool BackgroundParentImpl::DeallocPCookieStoreParent(
PCookieStoreParent* aActor) {
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
RefPtr<mozilla::dom::CookieStoreParent> actor =
dont_AddRef(static_cast<mozilla::dom::CookieStoreParent*>(aActor));
return true;
}
mozilla::dom::PServiceWorkerManagerParent*
BackgroundParentImpl::AllocPServiceWorkerManagerParent() {
AssertIsInMainProcess();

View File

@ -192,10 +192,6 @@ class BackgroundParentImpl : public PBackgroundParent {
bool DeallocPBroadcastChannelParent(PBroadcastChannelParent* aActor) override;
virtual PCookieStoreParent* AllocPCookieStoreParent() override;
virtual bool DeallocPCookieStoreParent(PCookieStoreParent* aActor) override;
PServiceWorkerManagerParent* AllocPServiceWorkerManagerParent() override;
bool DeallocPServiceWorkerManagerParent(

View File

@ -20,7 +20,6 @@ include protocol PCache;
include protocol PCacheStorage;
include protocol PCacheStreamControl;
include protocol PClientManager;
include protocol PCookieStore;
include protocol PEndpointForReport;
include protocol PFileSystemManager;
include protocol PFileSystemRequest;
@ -100,7 +99,6 @@ sync protocol PBackground
manages PCacheStorage;
manages PCacheStreamControl;
manages PClientManager;
manages PCookieStore;
manages PEndpointForReport;
manages PFileSystemRequest;
manages PGamepadEventChannel;
@ -199,8 +197,6 @@ parent:
async PUDPSocket(PrincipalInfo? pInfo, nsCString filter);
async PBroadcastChannel(PrincipalInfo pInfo, nsCString origin, nsString channel);
async PCookieStore();
async PServiceWorkerManager();
async ShutdownServiceWorkerRegistrar();

View File

@ -2348,12 +2348,6 @@
value: true
mirror: always
# Disable cookie-store API
- name: dom.cookieStore.enabled
type: RelaxedAtomicBool
value: false
mirror: always
# Is support for CSSPseudoElement enabled?
- name: dom.css_pseudo_element.enabled
type: bool
@ -12123,7 +12117,7 @@
# Whether to support CHIPS(Cookies Having Independent Partitioned State).
- name: network.cookie.CHIPS.enabled
type: RelaxedAtomicBool
type: bool
value: true
mirror: always

View File

@ -16,8 +16,6 @@
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/net/CookieJarSettings.h"
#include "mozilla/Unused.h"
#include "mozIThirdPartyUtil.h"
@ -25,12 +23,10 @@
#include "nsICookiePermission.h"
#include "nsICookieService.h"
#include "nsIEffectiveTLDService.h"
#include "nsIGlobalObject.h"
#include "nsIHttpChannel.h"
#include "nsIRedirectHistoryEntry.h"
#include "nsIWebProgressListener.h"
#include "nsNetUtil.h"
#include "nsSandboxFlags.h"
#include "nsScriptSecurityManager.h"
#include "ThirdPartyUtil.h"
@ -51,35 +47,31 @@ bool CookieCommons::DomainMatches(Cookie* aCookie, const nsACString& aHost) {
// static
bool CookieCommons::PathMatches(Cookie* aCookie, const nsACString& aPath) {
return PathMatches(aCookie->Path(), aPath);
}
const nsCString& cookiePath(aCookie->Path());
// static
bool CookieCommons::PathMatches(const nsACString& aCookiePath,
const nsACString& aPath) {
// if our cookie path is empty we can't really perform our prefix check, and
// also we can't check the last character of the cookie path, so we would
// never return a successful match.
if (aCookiePath.IsEmpty()) {
if (cookiePath.IsEmpty()) {
return false;
}
// if the cookie path and the request path are identical, they match.
if (aCookiePath.Equals(aPath)) {
if (cookiePath.Equals(aPath)) {
return true;
}
// if the cookie path is a prefix of the request path, and the last character
// of the cookie path is %x2F ("/"), they match.
bool isPrefix = StringBeginsWith(aPath, aCookiePath);
if (isPrefix && aCookiePath.Last() == '/') {
bool isPrefix = StringBeginsWith(aPath, cookiePath);
if (isPrefix && cookiePath.Last() == '/') {
return true;
}
// if the cookie path is a prefix of the request path, and the first character
// of the request path that is not included in the cookie path is a %x2F ("/")
// character, they match.
uint32_t cookiePathLen = aCookiePath.Length();
uint32_t cookiePathLen = cookiePath.Length();
return isPrefix && aPath[cookiePathLen] == '/';
}
@ -508,41 +500,30 @@ already_AddRefed<nsICookieJarSettings> CookieCommons::GetCookieJarSettings(
}
// static
bool CookieCommons::ShouldIncludeCrossSiteCookie(Cookie* aCookie,
bool aPartitionForeign,
bool aInPrivateBrowsing,
bool aUsingStorageAccess) {
bool CookieCommons::ShouldIncludeCrossSiteCookieForDocument(
Cookie* aCookie, dom::Document* aDocument) {
MOZ_ASSERT(aCookie);
MOZ_ASSERT(aDocument);
int32_t sameSiteAttr = 0;
aCookie->GetSameSite(&sameSiteAttr);
return ShouldIncludeCrossSiteCookie(
sameSiteAttr, aCookie->IsPartitioned() && aCookie->RawIsPartitioned(),
aPartitionForeign, aInPrivateBrowsing, aUsingStorageAccess);
}
// static
bool CookieCommons::ShouldIncludeCrossSiteCookie(int32_t aSameSiteAttr,
bool aCookiePartitioned,
bool aPartitionForeign,
bool aInPrivateBrowsing,
bool aUsingStorageAccess) {
// CHIPS - If a third-party has storage access it can access both it's
// partitioned and unpartitioned cookie jars, else its cookies are blocked.
//
// Note that we will only include partitioned cookies that have "partitioned"
// attribution if we enable opt-in partitioning.
if (aPartitionForeign &&
if (aDocument->CookieJarSettings()->GetPartitionForeign() &&
(StaticPrefs::network_cookie_cookieBehavior_optInPartitioning() ||
(aInPrivateBrowsing &&
(aDocument->IsInPrivateBrowsing() &&
StaticPrefs::
network_cookie_cookieBehavior_optInPartitioning_pbmode())) &&
!aCookiePartitioned && !aUsingStorageAccess) {
!(aCookie->IsPartitioned() && aCookie->RawIsPartitioned()) &&
!aDocument->UsingStorageAccess()) {
return false;
}
return aSameSiteAttr == nsICookie::SAMESITE_NONE;
return sameSiteAttr == nsICookie::SAMESITE_NONE;
}
bool CookieCommons::IsSafeTopLevelNav(nsIChannel* aChannel) {
@ -845,138 +826,6 @@ void CookieCommons::ComposeCookieString(nsTArray<RefPtr<Cookie>>& aCookieList,
}
}
// static
CookieCommons::SecurityChecksResult
CookieCommons::CheckGlobalAndRetrieveCookiePrincipals(
Document* aDocument, nsIPrincipal** aCookiePrincipal,
nsIPrincipal** aCookiePartitionedPrincipal) {
MOZ_ASSERT(aCookiePrincipal);
nsCOMPtr<nsIPrincipal> cookiePrincipal;
nsCOMPtr<nsIPrincipal> cookiePartitionedPrincipal;
if (!NS_IsMainThread()) {
MOZ_ASSERT(!aDocument);
dom::WorkerPrivate* workerPrivate = dom::GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
StorageAccess storageAccess = workerPrivate->StorageAccess();
if (storageAccess == StorageAccess::eDeny) {
return SecurityChecksResult::eDoNotContinue;
}
cookiePrincipal = workerPrivate->GetPrincipal();
if (NS_WARN_IF(!cookiePrincipal) || cookiePrincipal->GetIsNullPrincipal()) {
return SecurityChecksResult::eSecurityError;
}
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always
// available (and therefore the partitioned principal), the unpartitioned
// cookie jar is only available in first-party or third-party with
// storageAccess contexts. In both cases, the Worker will have storage
// access.
bool isCHIPS = StaticPrefs::network_cookie_CHIPS_enabled() &&
workerPrivate->CookieJarSettings()->GetPartitionForeign();
bool workerHasStorageAccess =
workerPrivate->StorageAccess() == StorageAccess::eAllow;
if (isCHIPS && workerHasStorageAccess) {
// Assert that the cookie principal is unpartitioned.
MOZ_ASSERT(
cookiePrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
// Only retrieve the partitioned originAttributes if the partitionKey is
// set. The partitionKey could be empty for partitionKey in partitioned
// originAttributes if the aWorker is for privilege context, such as the
// extension's background page.
nsCOMPtr<nsIPrincipal> partitionedPrincipal =
workerPrivate->GetPartitionedPrincipal();
if (partitionedPrincipal && !partitionedPrincipal->OriginAttributesRef()
.mPartitionKey.IsEmpty()) {
cookiePartitionedPrincipal = partitionedPrincipal;
}
}
} else {
if (!aDocument) {
return SecurityChecksResult::eDoNotContinue;
}
// If the document's sandboxed origin flag is set, then reading cookies
// is prohibited.
if (aDocument->GetSandboxFlags() & SANDBOXED_ORIGIN) {
return SecurityChecksResult::eSandboxedError;
}
cookiePrincipal = aDocument->EffectiveCookiePrincipal();
if (NS_WARN_IF(!cookiePrincipal) || cookiePrincipal->GetIsNullPrincipal()) {
return SecurityChecksResult::eSecurityError;
}
if (aDocument->CookieAccessDisabled()) {
return SecurityChecksResult::eDoNotContinue;
}
// GTests do not create an inner window and because of these a few security
// checks will block this method.
if (!StaticPrefs::dom_cookie_testing_enabled()) {
StorageAccess storageAccess = CookieAllowedForDocument(aDocument);
if (storageAccess == StorageAccess::eDeny) {
return SecurityChecksResult::eDoNotContinue;
}
if (ShouldPartitionStorage(storageAccess) &&
!StoragePartitioningEnabled(storageAccess,
aDocument->CookieJarSettings())) {
return SecurityChecksResult::eDoNotContinue;
}
// If the document is a cookie-averse Document... return the empty string.
if (aDocument->IsCookieAverse()) {
return SecurityChecksResult::eDoNotContinue;
}
}
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always
// available (and therefore the partitioned principal), the unpartitioned
// cookie jar is only available in first-party or third-party with
// storageAccess contexts. In both cases, the aDocument will have storage
// access.
bool isCHIPS = StaticPrefs::network_cookie_CHIPS_enabled() &&
aDocument->CookieJarSettings()->GetPartitionForeign();
bool documentHasStorageAccess = false;
nsresult rv = aDocument->HasStorageAccessSync(documentHasStorageAccess);
if (NS_WARN_IF(NS_FAILED(rv))) {
return SecurityChecksResult::eDoNotContinue;
}
if (isCHIPS && documentHasStorageAccess) {
// Assert that the cookie principal is unpartitioned.
MOZ_ASSERT(
cookiePrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
// Only append the partitioned originAttributes if the partitionKey is
// set. The partitionKey could be empty for partitionKey in partitioned
// originAttributes if the aDocument is for privilege context, such as the
// extension's background page.
if (!aDocument->PartitionedPrincipal()
->OriginAttributesRef()
.mPartitionKey.IsEmpty()) {
cookiePartitionedPrincipal = aDocument->PartitionedPrincipal();
}
}
}
if (!IsSchemeSupported(cookiePrincipal)) {
return SecurityChecksResult::eDoNotContinue;
}
cookiePrincipal.forget(aCookiePrincipal);
if (aCookiePartitionedPrincipal) {
cookiePartitionedPrincipal.forget(aCookiePartitionedPrincipal);
}
return SecurityChecksResult::eContinue;
}
// static
void CookieCommons::GetServerDateHeader(nsIChannel* aChannel,
nsACString& aServerDateHeader) {

View File

@ -69,9 +69,6 @@ class CookieCommons final {
static bool PathMatches(Cookie* aCookie, const nsACString& aPath);
static bool PathMatches(const nsACString& aCookiePath,
const nsACString& aPath);
static nsresult GetBaseDomain(nsIEffectiveTLDService* aTLDService,
nsIURI* aHostURI, nsACString& aBaseDomain,
bool& aRequireHostMatch);
@ -115,16 +112,8 @@ class CookieCommons final {
static already_AddRefed<nsICookieJarSettings> GetCookieJarSettings(
nsIChannel* aChannel);
static bool ShouldIncludeCrossSiteCookie(Cookie* aCookie,
bool aPartitionForeign,
bool aInPrivateBrowsing,
bool aUsingStorageAccess);
static bool ShouldIncludeCrossSiteCookie(int32_t aSameSiteAttr,
bool aCookiePartitioned,
bool aPartitionForeign,
bool aInPrivateBrowsing,
bool aUsingStorageAccess);
static bool ShouldIncludeCrossSiteCookieForDocument(Cookie* aCookie,
dom::Document* aDocument);
static bool IsSchemeSupported(nsIPrincipal* aPrincipal);
static bool IsSchemeSupported(nsIURI* aURI);
@ -156,26 +145,6 @@ class CookieCommons final {
static void GetServerDateHeader(nsIChannel* aChannel,
nsACString& aServerDateHeader);
enum class SecurityChecksResult {
// A sandboxed context detected.
eSandboxedError,
// A security error needs to be thrown.
eSecurityError,
// This context should not see cookies without returning errors.
eDoNotContinue,
// No security issues found. Proceed to expose cookies.
eContinue,
};
// Runs the security checks requied by specs on the current context (Document
// or Worker) to see if it's allowed to set/get cookies. In case it does
// (eContinue), the cookie principals are returned. Use the
// `aCookiePartitionedPrincipal` to retrieve CHIP cookies. Use
// `aCookiePrincipal` to retrieve non-CHIP cookies.
static SecurityChecksResult CheckGlobalAndRetrieveCookiePrincipals(
mozilla::dom::Document* aDocument, nsIPrincipal** aCookiePrincipal,
nsIPrincipal** aCookiePartitionedPrincipal);
};
} // namespace net

View File

@ -395,7 +395,7 @@ void CookieJarSettings::Serialize(CookieJarSettingsArgs& aData) {
continue;
}
mozilla::ipc::PrincipalInfo principalInfo;
ipc::PrincipalInfo principalInfo;
rv = PrincipalToPrincipalInfo(principal, &principalInfo,
true /* aSkipBaseDomain */);
if (NS_WARN_IF(NS_FAILED(rv))) {

View File

@ -62,13 +62,6 @@ CookieNotification::GetBrowsingContext(dom::BrowsingContext** aResult) {
return NS_OK;
}
NS_IMETHODIMP
CookieNotification::GetOperationID(nsID** aOperationID) {
NS_ENSURE_ARG_POINTER(aOperationID);
*aOperationID = mOperationID;
return NS_OK;
}
NS_IMPL_ISUPPORTS(CookieNotification, nsICookieNotification)
} // namespace mozilla::net

View File

@ -25,18 +25,13 @@ class CookieNotification final : public nsICookieNotification {
nsICookie* aCookie, const nsACString& aBaseDomain,
bool aIsThirdParty = false,
nsIArray* aBatchDeletedCookies = nullptr,
uint64_t aBrowsingContextId = 0,
const nsID* aOperationID = nullptr)
uint64_t aBrowsingContextId = 0)
: mAction(aAction),
mCookie(aCookie),
mBaseDomain(aBaseDomain),
mIsThirdParty(aIsThirdParty),
mBatchDeletedCookies(aBatchDeletedCookies),
mBrowsingContextId(aBrowsingContextId) {
if (aOperationID) {
mOperationID = aOperationID->Clone();
}
};
mBrowsingContextId(aBrowsingContextId) {};
private:
nsICookieNotification::Action mAction;
@ -45,13 +40,8 @@ class CookieNotification final : public nsICookieNotification {
bool mIsThirdParty;
nsCOMPtr<nsIArray> mBatchDeletedCookies;
uint64_t mBrowsingContextId = 0;
nsID* mOperationID = nullptr;
~CookieNotification() {
if (mOperationID) {
free(mOperationID);
}
}
~CookieNotification() = default;
};
} // namespace mozilla::net

View File

@ -704,8 +704,7 @@ CookieService::Add(const nsACString& aHost, const nsACString& aPath,
}
return AddNative(aHost, aPath, aName, aValue, aIsSecure, aIsHttpOnly,
aIsSession, aExpiry, &attrs, aSameSite, aSchemeMap, false,
nullptr);
aIsSession, aExpiry, &attrs, aSameSite, aSchemeMap);
}
NS_IMETHODIMP_(nsresult)
@ -713,8 +712,7 @@ CookieService::AddNative(const nsACString& aHost, const nsACString& aPath,
const nsACString& aName, const nsACString& aValue,
bool aIsSecure, bool aIsHttpOnly, bool aIsSession,
int64_t aExpiry, OriginAttributes* aOriginAttributes,
int32_t aSameSite, nsICookie::schemeType aSchemeMap,
bool aIsPartitioned, const nsID* aOperationID) {
int32_t aSameSite, nsICookie::schemeType aSchemeMap) {
if (NS_WARN_IF(!aOriginAttributes)) {
return NS_ERROR_FAILURE;
}
@ -740,8 +738,8 @@ CookieService::AddNative(const nsACString& aHost, const nsACString& aPath,
CookieStruct cookieData(nsCString(aName), nsCString(aValue), nsCString(aHost),
nsCString(aPath), aExpiry, currentTimeInUsec,
Cookie::GenerateUniqueCreationTime(currentTimeInUsec),
aIsHttpOnly, aIsSession, aIsSecure, aIsPartitioned,
aSameSite, aSameSite, aSchemeMap);
aIsHttpOnly, aIsSession, aIsSecure, false, aSameSite,
aSameSite, aSchemeMap);
RefPtr<Cookie> cookie = Cookie::Create(cookieData, key.mOriginAttributes);
MOZ_ASSERT(cookie);
@ -749,15 +747,14 @@ CookieService::AddNative(const nsACString& aHost, const nsACString& aPath,
CookieStorage* storage = PickStorage(*aOriginAttributes);
storage->AddCookie(nullptr, baseDomain, *aOriginAttributes, cookie,
currentTimeInUsec, nullptr, VoidCString(), true,
!aOriginAttributes->mPartitionKey.IsEmpty(), nullptr,
aOperationID);
!aOriginAttributes->mPartitionKey.IsEmpty(), nullptr);
return NS_OK;
}
nsresult CookieService::Remove(const nsACString& aHost,
const OriginAttributes& aAttrs,
const nsACString& aName, const nsACString& aPath,
const nsID* aOperationID) {
const nsACString& aName,
const nsACString& aPath) {
// first, normalize the hostname, and fail if it contains illegal characters.
nsAutoCString host(aHost);
nsresult rv = NormalizeHost(host);
@ -775,7 +772,7 @@ nsresult CookieService::Remove(const nsACString& aHost,
CookieStorage* storage = PickStorage(aAttrs);
storage->RemoveCookie(baseDomain, aAttrs, host, PromiseFlatCString(aName),
PromiseFlatCString(aPath), aOperationID);
PromiseFlatCString(aPath));
return NS_OK;
}
@ -790,19 +787,18 @@ CookieService::Remove(const nsACString& aHost, const nsACString& aName,
return NS_ERROR_INVALID_ARG;
}
return RemoveNative(aHost, aName, aPath, &attrs, nullptr);
return RemoveNative(aHost, aName, aPath, &attrs);
}
NS_IMETHODIMP_(nsresult)
CookieService::RemoveNative(const nsACString& aHost, const nsACString& aName,
const nsACString& aPath,
OriginAttributes* aOriginAttributes,
const nsID* aOperationID) {
OriginAttributes* aOriginAttributes) {
if (NS_WARN_IF(!aOriginAttributes)) {
return NS_ERROR_FAILURE;
}
nsresult rv = Remove(aHost, *aOriginAttributes, aName, aPath, aOperationID);
nsresult rv = Remove(aHost, *aOriginAttributes, aName, aPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -1270,18 +1266,6 @@ CookieService::GetCookiesFromHost(const nsACString& aHost,
JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx,
nsTArray<RefPtr<nsICookie>>& aResult) {
OriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
return GetCookiesFromHostNative(aHost, &attrs, aResult);
}
NS_IMETHODIMP
CookieService::GetCookiesFromHostNative(const nsACString& aHost,
OriginAttributes* aAttrs,
nsTArray<RefPtr<nsICookie>>& aResult) {
// first, normalize the hostname, and fail if it contains illegal characters.
nsAutoCString host(aHost);
nsresult rv = NormalizeHost(host);
@ -1291,14 +1275,19 @@ CookieService::GetCookiesFromHostNative(const nsACString& aHost,
rv = CookieCommons::GetBaseDomainFromHost(mTLDService, host, baseDomain);
NS_ENSURE_SUCCESS(rv, rv);
OriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
if (!IsInitialized()) {
return NS_ERROR_NOT_AVAILABLE;
}
CookieStorage* storage = PickStorage(*aAttrs);
CookieStorage* storage = PickStorage(attrs);
nsTArray<RefPtr<Cookie>> cookies;
storage->GetCookiesFromHost(baseDomain, *aAttrs, cookies);
storage->GetCookiesFromHost(baseDomain, attrs, cookies);
if (cookies.IsEmpty()) {
return NS_OK;
@ -1439,7 +1428,7 @@ class RemoveAllSinceRunnable : public Runnable {
auto* cookie = static_cast<Cookie*>(mList[mIndex].get());
if (cookie->CreationTime() > mSinceWhen &&
NS_FAILED(mSelf->Remove(cookie->Host(), cookie->OriginAttributesRef(),
cookie->Name(), cookie->Path(), nullptr))) {
cookie->Name(), cookie->Path()))) {
continue;
}
}

View File

@ -89,8 +89,7 @@ class CookieService final : public nsICookieService,
* with OriginAttributes parameter.
*/
nsresult Remove(const nsACString& aHost, const OriginAttributes& aAttrs,
const nsACString& aName, const nsACString& aPath,
const nsID* aOperationID);
const nsACString& aName, const nsACString& aPath);
bool SetCookiesFromIPC(const nsACString& aBaseDomain,
const OriginAttributes& aAttrs, nsIURI* aHostURI,

View File

@ -6,7 +6,6 @@
#include "Cookie.h"
#include "CookieCommons.h"
#include "CookieLogging.h"
#include "CookieNotification.h"
#include "CookieParser.h"
#include "CookieService.h"
#include "mozilla/net/CookieServiceChild.h"
@ -182,10 +181,9 @@ IPCResult CookieServiceChild::RecvRemoveAll() {
return IPC_OK();
}
IPCResult CookieServiceChild::RecvRemoveCookie(
const CookieStruct& aCookie, const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID) {
RemoveSingleCookie(aCookie, aAttrs, aOperationID);
IPCResult CookieServiceChild::RecvRemoveCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs) {
RemoveSingleCookie(aCookie, aAttrs);
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
if (obsService) {
@ -195,8 +193,7 @@ IPCResult CookieServiceChild::RecvRemoveCookie(
}
void CookieServiceChild::RemoveSingleCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID) {
const OriginAttributes& aAttrs) {
nsCString baseDomain;
CookieCommons::GetBaseDomainFromHost(mTLDService, aCookie.host(), baseDomain);
CookieKey key(baseDomain, aAttrs);
@ -208,7 +205,7 @@ void CookieServiceChild::RemoveSingleCookie(const CookieStruct& aCookie,
}
for (uint32_t i = 0; i < cookiesList->Length(); i++) {
RefPtr<Cookie> cookie = cookiesList->ElementAt(i);
Cookie* cookie = cookiesList->ElementAt(i);
// bug 1858366: In the case that we are updating a stale cookie
// from the content process: the parent process will signal
// a batch deletion for the old cookie.
@ -220,20 +217,15 @@ void CookieServiceChild::RemoveSingleCookie(const CookieStruct& aCookie,
cookie->Path().Equals(aCookie.path()) &&
cookie->Expiry() <= aCookie.expiry()) {
cookiesList->RemoveElementAt(i);
NotifyObservers(cookie, aAttrs, CookieNotificationAction::CookieDeleted,
aOperationID);
break;
}
}
}
IPCResult CookieServiceChild::RecvAddCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID) {
const OriginAttributes& aAttrs) {
RefPtr<Cookie> cookie = Cookie::Create(aCookie, aAttrs);
CookieNotificationAction action = RecordDocumentCookie(cookie, aAttrs);
NotifyObservers(cookie, aAttrs, action, aOperationID);
RecordDocumentCookie(cookie, aAttrs);
// signal test code to check their cookie list
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
@ -250,7 +242,7 @@ IPCResult CookieServiceChild::RecvRemoveBatchDeletedCookies(
MOZ_ASSERT(aCookiesList.Length() == aAttrsList.Length());
for (uint32_t i = 0; i < aCookiesList.Length(); i++) {
CookieStruct cookieStruct = aCookiesList.ElementAt(i);
RemoveSingleCookie(cookieStruct, aAttrsList.ElementAt(i), Nothing());
RemoveSingleCookie(cookieStruct, aAttrsList.ElementAt(i));
}
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
@ -301,9 +293,8 @@ IPCResult CookieServiceChild::RecvTrackCookiesLoad(
nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
}
CookieServiceChild::CookieNotificationAction
CookieServiceChild::RecordDocumentCookie(Cookie* aCookie,
const OriginAttributes& aAttrs) {
void CookieServiceChild::RecordDocumentCookie(Cookie* aCookie,
const OriginAttributes& aAttrs) {
nsAutoCString baseDomain;
CookieCommons::GetBaseDomainFromHost(mTLDService, aCookie->Host(),
baseDomain);
@ -315,9 +306,6 @@ CookieServiceChild::RecordDocumentCookie(Cookie* aCookie,
if (!cookiesList) {
cookiesList = mCookiesMap.GetOrInsertNew(key);
}
bool cookieFound = false;
for (uint32_t i = 0; i < cookiesList->Length(); i++) {
Cookie* cookie = cookiesList->ElementAt(i);
if (cookie->Name().Equals(aCookie->Name()) &&
@ -331,22 +319,19 @@ CookieServiceChild::RecordDocumentCookie(Cookie* aCookie,
cookie->IsSession() == aCookie->IsSession() &&
cookie->IsHttpOnly() == aCookie->IsHttpOnly()) {
cookie->SetLastAccessed(aCookie->LastAccessed());
return CookieNotificationAction::NoActionNeeded;
return;
}
cookiesList->RemoveElementAt(i);
cookieFound = true;
break;
}
}
int64_t currentTime = PR_Now() / PR_USEC_PER_SEC;
if (aCookie->Expiry() <= currentTime) {
return CookieNotificationAction::CookieDeleted;
return;
}
cookiesList->AppendElement(aCookie);
return cookieFound ? CookieNotificationAction::CookieChanged
: CookieNotificationAction::CookieAdded;
}
NS_IMETHODIMP
@ -513,10 +498,7 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
cookie->SetCreationTime(
Cookie::GenerateUniqueCreationTime(currentTimeInUsec));
CookieNotificationAction action =
RecordDocumentCookie(cookie, cookieOriginAttributes);
NotifyObservers(cookie, cookieOriginAttributes, action);
RecordDocumentCookie(cookie, cookieOriginAttributes);
cookiesToSendRef.AppendElement(parser.CookieData());
} while (moreCookies);
@ -619,9 +601,7 @@ void CookieServiceChild::AddCookieFromDocument(
}
}
CookieNotificationAction action =
RecordDocumentCookie(&aCookie, aOriginAttributes);
NotifyObservers(&aCookie, aOriginAttributes, action);
RecordDocumentCookie(&aCookie, aOriginAttributes);
if (CanSend()) {
nsTArray<CookieStruct> cookiesToSend;
@ -644,46 +624,5 @@ void CookieServiceChild::AddCookieFromDocument(
}
}
void CookieServiceChild::NotifyObservers(Cookie* aCookie,
const OriginAttributes& aAttrs,
CookieNotificationAction aAction,
const Maybe<nsID>& aOperationID) {
nsICookieNotification::Action notificationAction;
switch (aAction) {
case CookieNotificationAction::NoActionNeeded:
return;
case CookieNotificationAction::CookieAdded:
notificationAction = nsICookieNotification::COOKIE_ADDED;
break;
case CookieNotificationAction::CookieChanged:
notificationAction = nsICookieNotification::COOKIE_CHANGED;
break;
case CookieNotificationAction::CookieDeleted:
notificationAction = nsICookieNotification::COOKIE_DELETED;
break;
}
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (!os) {
return;
}
nsAutoCString baseDomain;
CookieCommons::GetBaseDomainFromHost(mTLDService, aCookie->Host(),
baseDomain);
nsCOMPtr<nsICookieNotification> notification =
new CookieNotification(notificationAction, aCookie, baseDomain, false,
nullptr, 0, aOperationID.ptrOr(nullptr));
os->NotifyObservers(
notification,
aAttrs.IsPrivateBrowsing() ? "private-cookie-changed" : "cookie-changed",
u"");
}
} // namespace net
} // namespace mozilla

View File

@ -46,19 +46,7 @@ class CookieServiceChild final : public PCookieServiceChild,
private:
~CookieServiceChild();
enum class CookieNotificationAction {
NoActionNeeded,
CookieAdded,
CookieChanged,
CookieDeleted,
};
CookieNotificationAction RecordDocumentCookie(Cookie* aCookie,
const OriginAttributes& aAttrs);
void NotifyObservers(Cookie* aCookie, const OriginAttributes& aAttrs,
CookieNotificationAction aAction,
const Maybe<nsID>& aOperationID = Nothing());
void RecordDocumentCookie(Cookie* aCookie, const OriginAttributes& aAttrs);
static bool RequireThirdPartyCheck(nsILoadInfo* aLoadInfo);
@ -72,16 +60,13 @@ class CookieServiceChild final : public PCookieServiceChild,
nsTArray<OriginAttributes>&& aAttrsList);
mozilla::ipc::IPCResult RecvRemoveCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID);
const OriginAttributes& aAttrs);
mozilla::ipc::IPCResult RecvAddCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID);
const OriginAttributes& aAttrs);
void RemoveSingleCookie(const CookieStruct& aCookie,
const OriginAttributes& aAttrs,
const Maybe<nsID>& aOperationID);
const OriginAttributes& aAttrs);
CookiesMap mCookiesMap;
nsCOMPtr<mozIThirdPartyUtil> mThirdPartyUtil;

View File

@ -6,9 +6,9 @@
#include "CookieCommons.h"
#include "CookieLogging.h"
#include "CookieServiceParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/net/CookieService.h"
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/StoragePrincipalHelper.h"
@ -25,9 +25,7 @@ using namespace mozilla::ipc;
namespace mozilla {
namespace net {
CookieServiceParent::CookieServiceParent(dom::ContentParent* aContentParent) {
MOZ_ASSERT(aContentParent);
CookieServiceParent::CookieServiceParent() {
// Instantiate the cookieservice via the service manager, so it sticks around
// until shutdown.
nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
@ -40,14 +38,6 @@ CookieServiceParent::CookieServiceParent(dom::ContentParent* aContentParent) {
MOZ_ALWAYS_TRUE(mTLDService);
mProcessingCookie = false;
nsTArray<nsCOMPtr<nsIPrincipal>> list;
aContentParent->TakeCookieInProcessCache(list);
for (nsIPrincipal* principal : list) {
nsCOMPtr<nsIURI> uri = principal->GetURI();
UpdateCookieInContentList(uri, principal->OriginAttributesRef());
}
}
void CookieServiceParent::RemoveBatchDeletedCookies(nsIArray* aCookieList) {
@ -76,8 +66,7 @@ void CookieServiceParent::RemoveBatchDeletedCookies(nsIArray* aCookieList) {
void CookieServiceParent::RemoveAll() { Unused << SendRemoveAll(); }
void CookieServiceParent::RemoveCookie(const Cookie& cookie,
const nsID* aOperationID) {
void CookieServiceParent::RemoveCookie(const Cookie& cookie) {
const OriginAttributes& attrs = cookie.OriginAttributesRef();
CookieStruct cookieStruct = cookie.ToIPC();
@ -86,12 +75,10 @@ void CookieServiceParent::RemoveCookie(const Cookie& cookie,
if (cookie.IsHttpOnly() || !InsecureCookieOrSecureOrigin(cookie)) {
cookieStruct.value() = "";
}
Unused << SendRemoveCookie(cookieStruct, attrs,
aOperationID ? Some(*aOperationID) : Nothing());
Unused << SendRemoveCookie(cookieStruct, attrs);
}
void CookieServiceParent::AddCookie(const Cookie& cookie,
const nsID* aOperationID) {
void CookieServiceParent::AddCookie(const Cookie& cookie) {
const OriginAttributes& attrs = cookie.OriginAttributesRef();
CookieStruct cookieStruct = cookie.ToIPC();
@ -100,23 +87,17 @@ void CookieServiceParent::AddCookie(const Cookie& cookie,
if (cookie.IsHttpOnly() || !InsecureCookieOrSecureOrigin(cookie)) {
cookieStruct.value() = "";
}
Unused << SendAddCookie(cookieStruct, attrs,
aOperationID ? Some(*aOperationID) : Nothing());
Unused << SendAddCookie(cookieStruct, attrs);
}
bool CookieServiceParent::ContentProcessHasCookie(const Cookie& cookie) {
return ContentProcessHasCookie(cookie.Host(), cookie.OriginAttributesRef());
}
bool CookieServiceParent::ContentProcessHasCookie(
const nsACString& aHost, const OriginAttributes& aOriginAttributes) {
nsCString baseDomain;
if (NS_WARN_IF(NS_FAILED(CookieCommons::GetBaseDomainFromHost(
mTLDService, aHost, baseDomain)))) {
mTLDService, cookie.Host(), baseDomain)))) {
return false;
}
CookieKey cookieKey(baseDomain, aOriginAttributes);
CookieKey cookieKey(baseDomain, cookie.OriginAttributesRef());
return mCookieKeysInContent.MaybeGet(cookieKey).isSome();
}
@ -307,14 +288,6 @@ IPCResult CookieServiceParent::RecvSetCookies(
const nsCString& aBaseDomain, const OriginAttributes& aOriginAttributes,
nsIURI* aHost, bool aFromHttp, bool aIsThirdParty,
const nsTArray<CookieStruct>& aCookies) {
if (!ContentProcessHasCookie(aBaseDomain, aOriginAttributes)) {
#ifdef NIGHTLY_BUILD
return IPC_FAIL(this, "Invalid set-cookie request from content process");
#else
return IPC_OK();
#endif
}
return SetCookies(aBaseDomain, aOriginAttributes, aHost, aFromHttp,
aIsThirdParty, aCookies);
}

View File

@ -13,11 +13,7 @@ class nsIArray;
class nsICookie;
namespace mozilla {
class OriginAttributes;
namespace dom {
class ContentParent;
} // namespace dom
} // namespace mozilla
}
class nsIEffectiveTLDService;
@ -31,7 +27,7 @@ class CookieServiceParent : public PCookieServiceParent {
friend class PCookieServiceParent;
public:
explicit CookieServiceParent(dom::ContentParent* aContentParent);
CookieServiceParent();
virtual ~CookieServiceParent() = default;
void TrackCookieLoad(nsIChannel* aChannel);
@ -40,9 +36,9 @@ class CookieServiceParent : public PCookieServiceParent {
void RemoveAll();
void RemoveCookie(const Cookie& aCookie, const nsID* aOperationID);
void RemoveCookie(const Cookie& aCookie);
void AddCookie(const Cookie& aCookie, const nsID* aOperationID);
void AddCookie(const Cookie& aCookie);
// This will return true if the CookieServiceParent is currently processing
// an update from the content process. This is used in ContentParent to make
@ -51,8 +47,6 @@ class CookieServiceParent : public PCookieServiceParent {
bool ProcessingCookie() { return mProcessingCookie; }
bool ContentProcessHasCookie(const Cookie& cookie);
bool ContentProcessHasCookie(const nsACString& aHost,
const OriginAttributes& aOriginAttributes);
bool InsecureCookieOrSecureOrigin(const Cookie& cookie);
void UpdateCookieInContentList(nsIURI* aHostURI,
const OriginAttributes& aOriginAttrs);

View File

@ -318,8 +318,7 @@ void CookieStorage::RemoveCookie(const nsACString& aBaseDomain,
const OriginAttributes& aOriginAttributes,
const nsACString& aHost,
const nsACString& aName,
const nsACString& aPath,
const nsID* aOperationID) {
const nsACString& aPath) {
CookieListIter matchIter{};
RefPtr<Cookie> cookie;
if (FindCookie(aBaseDomain, aOriginAttributes, aHost, aName, aPath,
@ -330,8 +329,7 @@ void CookieStorage::RemoveCookie(const nsACString& aBaseDomain,
if (cookie) {
// Everything's done. Notify observers.
NotifyChanged(cookie, nsICookieNotification::COOKIE_DELETED, aBaseDomain,
aOperationID);
NotifyChanged(cookie, nsICookieNotification::COOKIE_DELETED, aBaseDomain);
}
}
@ -487,8 +485,7 @@ void CookieStorage::NotifyChanged(nsISupports* aSubject,
const nsACString& aBaseDomain,
bool aIsThirdParty,
dom::BrowsingContext* aBrowsingContext,
bool aOldCookieIsSession,
const nsID* aOperationID) {
bool aOldCookieIsSession) {
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (!os) {
return;
@ -508,9 +505,9 @@ void CookieStorage::NotifyChanged(nsISupports* aSubject,
browsingContextId = aBrowsingContext->Id();
}
nsCOMPtr<nsICookieNotification> notification = new CookieNotification(
aAction, cookie, aBaseDomain, aIsThirdParty, batchDeletedCookies,
browsingContextId, aOperationID);
nsCOMPtr<nsICookieNotification> notification =
new CookieNotification(aAction, cookie, aBaseDomain, aIsThirdParty,
batchDeletedCookies, browsingContextId);
// Notify for topic "private-cookie-changed" or "cookie-changed"
os->NotifyObservers(notification, NotificationTopic(), u"");
@ -596,8 +593,7 @@ void CookieStorage::AddCookie(CookieParser* aCookieParser,
Cookie* aCookie, int64_t aCurrentTimeInUsec,
nsIURI* aHostURI, const nsACString& aCookieHeader,
bool aFromHttp, bool aIsThirdParty,
dom::BrowsingContext* aBrowsingContext,
const nsID* aOperationID) {
dom::BrowsingContext* aBrowsingContext) {
int64_t currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
CookieListIter exactIter{};
@ -711,8 +707,7 @@ void CookieStorage::AddCookie(CookieParser* aCookieParser,
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
"previously stored cookie was deleted");
NotifyChanged(oldCookie, nsICookieNotification::COOKIE_DELETED,
aBaseDomain, false, aBrowsingContext, oldCookieIsSession,
aOperationID);
aBaseDomain, false, aBrowsingContext, oldCookieIsSession);
return;
}
@ -839,7 +834,7 @@ void CookieStorage::AddCookie(CookieParser* aCookieParser,
// because observers may themselves attempt to mutate the list.
if (purgedList) {
NotifyChanged(purgedList, nsICookieNotification::COOKIES_BATCH_DELETED,
""_ns, false, nullptr, false, aOperationID);
""_ns);
}
// Notify for topic "private-cookie-changed" or "cookie-changed"
@ -847,7 +842,7 @@ void CookieStorage::AddCookie(CookieParser* aCookieParser,
foundCookie ? nsICookieNotification::COOKIE_CHANGED
: nsICookieNotification::COOKIE_ADDED,
aBaseDomain, aIsThirdParty, aBrowsingContext,
oldCookieIsSession, aOperationID);
oldCookieIsSession);
}
void CookieStorage::UpdateCookieOldestTime(Cookie* aCookie) {

View File

@ -109,7 +109,7 @@ class CookieStorage : public nsIObserver, public nsSupportsWeakReference {
void RemoveCookie(const nsACString& aBaseDomain,
const OriginAttributes& aOriginAttributes,
const nsACString& aHost, const nsACString& aName,
const nsACString& aPath, const nsID* aOperationID);
const nsACString& aPath);
virtual void RemoveCookiesWithOriginAttributes(
const OriginAttributesPattern& aPattern, const nsACString& aBaseDomain);
@ -124,15 +124,13 @@ class CookieStorage : public nsIObserver, public nsSupportsWeakReference {
nsICookieNotification::Action aAction,
const nsACString& aBaseDomain, bool aIsThirdParty = false,
dom::BrowsingContext* aBrowsingContext = nullptr,
bool aOldCookieIsSession = false,
const nsID* aOperationID = nullptr);
bool aOldCookieIsSession = false);
void AddCookie(CookieParser* aCookieParser, const nsACString& aBaseDomain,
const OriginAttributes& aOriginAttributes, Cookie* aCookie,
int64_t aCurrentTimeInUsec, nsIURI* aHostURI,
const nsACString& aCookieHeader, bool aFromHttp,
bool aIsThirdParty, dom::BrowsingContext* aBrowsingContext,
const nsID* aOperationID = nullptr);
bool aIsThirdParty, dom::BrowsingContext* aBrowsingContext);
// return true if we finish within the byte limit
bool RemoveCookiesFromBackUntilUnderLimit(

View File

@ -10,8 +10,6 @@ include NeckoChannelParams;
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
[RefCounted] using class nsIURI from "mozilla/ipc/URIUtils.h";
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
using struct nsID from "nsID.h";
namespace mozilla {
namespace net {
@ -59,8 +57,7 @@ child:
async TrackCookiesLoad(CookieStructTable[] cookiesListTable);
async RemoveCookie(CookieStruct cookie,
OriginAttributes attrs,
nsID? operationId);
OriginAttributes attrs);
async RemoveBatchDeletedCookies(CookieStruct[] cookiesList,
OriginAttributes[] attrsList);
@ -68,8 +65,8 @@ child:
async RemoveAll();
async AddCookie(CookieStruct cookie,
OriginAttributes attrs,
nsID? operationId);
OriginAttributes attrs);
};
}

View File

@ -80,8 +80,7 @@ interface nsICookieManager : nsISupports
nsresult removeNative(in AUTF8String aHost,
in ACString aName,
in AUTF8String aPath,
in OriginAttributesPtr aOriginAttributes,
in nsIDPtr aOperationID);
in OriginAttributesPtr aOriginAttributes);
/**
* Add a cookie. nsICookieService is the normal way to do this. This
@ -143,9 +142,7 @@ interface nsICookieManager : nsISupports
in int64_t aExpiry,
in OriginAttributesPtr aOriginAttributes,
in int32_t aSameSite,
in nsICookie_schemeType aSchemeMap,
in boolean aIsPartitioned,
in nsIDPtr aOperationID);
in nsICookie_schemeType aSchemeMap);
/**
* Find whether a given cookie already exists.
@ -232,11 +229,6 @@ interface nsICookieManager : nsISupports
Array<nsICookie> getCookiesFromHost(in AUTF8String aHost,
in jsval aOriginAttributes);
[notxpcom]
nsresult getCookiesFromHostNative(in AUTF8String aHost,
in OriginAttributesPtr aOriginAttributes,
out Array<nsICookie> aCookies);
/**
* Returns an array of all cookies whose origin attributes matches aPattern
*

View File

@ -72,10 +72,4 @@ interface nsICookieNotification : nsISupports {
* BrowsingContext associated with browsingContextId. May be nullptr.
*/
[infallible] readonly attribute BrowsingContext browsingContext;
/**
* Operation ID to track which nsICookieManager operation has generated
* this notification.
*/
readonly attribute nsIDPtr operationID;
};

View File

@ -287,7 +287,7 @@ mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor(
}
PCookieServiceParent* NeckoParent::AllocPCookieServiceParent() {
return new CookieServiceParent(static_cast<ContentParent*>(Manager()));
return new CookieServiceParent();
}
bool NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs) {

View File

@ -747,10 +747,7 @@ TEST(TestCookie, TestCookieMain)
INT64_MAX, // expiry time
&attrs, // originAttributes
nsICookie::SAMESITE_NONE,
nsICookie::SCHEME_HTTPS,
false, // is partitioned
nullptr // operation ID
)));
nsICookie::SCHEME_HTTPS)));
EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->AddNative(
"cookiemgr.test"_ns, // domain
"/foo"_ns, // path
@ -761,10 +758,7 @@ TEST(TestCookie, TestCookieMain)
true, // is session
PR_Now() / PR_USEC_PER_SEC + 2, // expiry time
&attrs, // originAttributes
nsICookie::SAMESITE_NONE, nsICookie::SCHEME_HTTPS,
false, // is partitioned
nullptr // operation ID
)));
nsICookie::SAMESITE_NONE, nsICookie::SCHEME_HTTPS)));
EXPECT_TRUE(NS_SUCCEEDED(cookieMgr2->AddNative("new.domain"_ns, // domain
"/rabbit"_ns, // path
"test3"_ns, // name
@ -775,10 +769,7 @@ TEST(TestCookie, TestCookieMain)
INT64_MAX, // expiry time
&attrs, // originAttributes
nsICookie::SAMESITE_NONE,
nsICookie::SCHEME_HTTPS,
false, // is partitioned
nullptr // operation ID
)));
nsICookie::SCHEME_HTTPS)));
// confirm using enumerator
nsTArray<RefPtr<nsICookie>> cookies;
EXPECT_NS_SUCCEEDED(cookieMgr->GetCookies(cookies));

View File

@ -1,4 +1,3 @@
# https://bugzilla.mozilla.org/show_bug.cgi?id=1475599
prefs: [dom.cookieStore.enabled:true]
implementation-status: backlog
lsan-allowed: [Alloc, Malloc, Then, mozilla::BasePrincipal::CreateContentPrincipal, mozilla::dom::DocGroup::Create, mozilla::dom::ServiceWorkerJobQueue::RunJob, mozilla::dom::ServiceWorkerManager::Unregister, mozilla::dom::ServiceWorkerRegistrationMainThread::Unregister, mozilla::dom::UnregisterCallback::UnregisterCallback, mozilla::net::nsStandardURL::TemplatedMutator, operator]

View File

@ -0,0 +1,12 @@
[change_eventhandler_for_document_cookie.https.window.html]
[document.cookie set/overwrite/delete observed by CookieStore]
expected: FAIL
[CookieStore set/overwrite/delete observed by document.cookie]
expected: FAIL
[CookieStore agrees with document.cookie on encoding non-ASCII cookies]
expected: FAIL
[document.cookie agrees with CookieStore on encoding non-ASCII cookies]
expected: FAIL

View File

@ -0,0 +1,15 @@
[change_eventhandler_for_http_cookie_and_set_cookie_headers.https.window.html]
[HTTP set/overwrite/delete observed in CookieStore]
expected: FAIL
[CookieStore agreed with HTTP headers agree on encoding non-ASCII cookies]
expected: FAIL
[CookieStore set/overwrite/delete observed in HTTP headers]
expected: FAIL
[HTTP headers agreed with CookieStore on encoding non-ASCII cookies]
expected: FAIL
[Binary HTTP set/overwrite/delete observed in CookieStore]
expected: FAIL

View File

@ -0,0 +1,3 @@
[change_eventhandler_for_no_name_and_no_value.https.window.html]
[Verify behavior of no-name and no-value cookies.]
expected: FAIL

View File

@ -0,0 +1,3 @@
[change_eventhandler_for_no_name_equals_in_value.https.window.html]
[Verify that attempting to set a cookie with no name and with '=' in the value does not work.]
expected: FAIL

View File

@ -0,0 +1,3 @@
[change_eventhandler_for_no_name_multiple_values.https.window.html]
[Verify behavior of multiple no-name cookies]
expected: FAIL

View File

@ -0,0 +1,88 @@
[cookieStore_delete_arguments.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.delete with positional name]
expected: FAIL
[cookieStore.delete with name in options]
expected: FAIL
[cookieStore.delete domain starts with "."]
expected: FAIL
[cookieStore.delete with domain that is not equal current host]
expected: FAIL
[cookieStore.delete with domain set to the current hostname]
expected: FAIL
[cookieStore.delete with domain set to a subdomain of the current hostname]
expected: FAIL
[cookieStore.delete with domain set to a non-domain-matching suffix of the current hostname]
expected: FAIL
[cookieStore.delete with path set to the current directory]
expected: FAIL
[cookieStore.delete with path set to subdirectory of the current directory]
expected: FAIL
[cookieStore.delete with missing / at the end of path]
expected: FAIL
[cookieStore.delete with path that does not start with /]
expected: FAIL
[cookieStore.delete with get result]
expected: FAIL
[cookieStore.delete with positional empty name]
expected: FAIL
[cookieStore.delete with empty name in options]
expected: FAIL
[cookieStore_delete_arguments.https.any.html]
[cookieStore.delete with positional name]
expected: FAIL
[cookieStore.delete with name in options]
expected: FAIL
[cookieStore.delete domain starts with "."]
expected: FAIL
[cookieStore.delete with domain that is not equal current host]
expected: FAIL
[cookieStore.delete with domain set to the current hostname]
expected: FAIL
[cookieStore.delete with domain set to a subdomain of the current hostname]
expected: FAIL
[cookieStore.delete with domain set to a non-domain-matching suffix of the current hostname]
expected: FAIL
[cookieStore.delete with path set to the current directory]
expected: FAIL
[cookieStore.delete with path set to subdirectory of the current directory]
expected: FAIL
[cookieStore.delete with missing / at the end of path]
expected: FAIL
[cookieStore.delete with path that does not start with /]
expected: FAIL
[cookieStore.delete with get result]
expected: FAIL
[cookieStore.delete with positional empty name]
expected: FAIL
[cookieStore.delete with empty name in options]
expected: FAIL

View File

@ -0,0 +1,10 @@
[cookieStore_delete_basic.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.delete return type is Promise<void>]
expected: FAIL
[cookieStore_delete_basic.https.any.html]
[cookieStore.delete return type is Promise<void>]
expected: FAIL

View File

@ -0,0 +1,12 @@
[cookieStore_event_arguments.https.window.html]
[CookieChangeEvent construction with default arguments]
expected: FAIL
[CookieChangeEvent construction with changed cookie list]
expected: FAIL
[CookieChangeEvent construction with deleted cookie list]
expected: FAIL
[CookieChangeEvent construction with changed and deleted cookie lists]
expected: FAIL

View File

@ -0,0 +1,4 @@
[cookieStore_event_basic.https.window.html]
expected: ERROR
[cookieStore fires change event for cookie set by cookieStore.set()]
expected: FAIL

View File

@ -0,0 +1,3 @@
[cookieStore_event_delete.https.window.html]
[cookieStore fires change event for cookie deleted by cookieStore.delete()]
expected: FAIL

View File

@ -0,0 +1,3 @@
[cookieStore_event_overwrite.https.window.html]
[cookieStore fires change event for cookie overwritten by cookieStore.set()]
expected: FAIL

View File

@ -1,3 +1,58 @@
[cookieStore_getAll_arguments.https.any.serviceworker.html]
[cookieStore_getAll_arguments.https.any.html]
[cookieStore.getAll with no arguments]
expected: FAIL
[cookieStore.getAll with empty options]
expected: FAIL
[cookieStore.getAll with positional name]
expected: FAIL
[cookieStore.getAll with name in options]
expected: FAIL
[cookieStore.getAll with name in both positional arguments and options]
expected: FAIL
[cookieStore.getAll with absolute url in options]
expected: FAIL
[cookieStore.getAll with relative url in options]
expected: FAIL
[cookieStore.getAll with invalid url path in options]
expected: FAIL
[cookieStore.getAll with invalid url host in options]
expected: FAIL
[cookieStore_getAll_arguments.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.getAll with no arguments]
expected: FAIL
[cookieStore.getAll with empty options]
expected: FAIL
[cookieStore.getAll with positional name]
expected: FAIL
[cookieStore.getAll with name in options]
expected: FAIL
[cookieStore.getAll with name in both positional arguments and options]
expected: FAIL
[cookieStore.getAll with absolute url in options]
expected: FAIL
[cookieStore.getAll with relative url in options]
expected: FAIL
[cookieStore.getAll with invalid url path in options]
expected: FAIL
[cookieStore.getAll with invalid url host in options]
expected: FAIL

View File

@ -0,0 +1,10 @@
[cookieStore_getAll_multiple.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.getAll returns multiple cookies written by cookieStore.set]
expected: FAIL
[cookieStore_getAll_multiple.https.any.html]
[cookieStore.getAll returns multiple cookies written by cookieStore.set]
expected: FAIL

View File

@ -0,0 +1,10 @@
[cookieStore_getAll_set_basic.https.any.html]
[cookieStore.getAll returns the cookie written by cookieStore.set]
expected: FAIL
[cookieStore_getAll_set_basic.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.getAll returns the cookie written by cookieStore.set]
expected: FAIL

View File

@ -1,16 +1,58 @@
[cookieStore_get_arguments.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.get with no arguments returns TypeError]
expected: FAIL
[cookieStore.get with empty options returns TypeError]
expected: FAIL
[cookieStore.get with positional name]
expected: FAIL
[cookieStore.get with name in options]
expected: FAIL
[cookieStore.get with name in both positional arguments and options]
expected: FAIL
[cookieStore.get with absolute url in options]
expected: FAIL
[cookieStore.get with relative url in options]
expected: FAIL
[cookieStore.get with invalid url path in options]
expected: FAIL
[cookieStore.get with invalid url host in options]
expected: FAIL
[cookieStore_get_arguments.https.any.html]
[cookieStore.get with no arguments returns TypeError]
expected: FAIL
[cookieStore.get with empty options returns TypeError]
expected: FAIL
[cookieStore.get with positional name]
expected: FAIL
[cookieStore.get with name in options]
expected: FAIL
[cookieStore.get with name in both positional arguments and options]
expected: FAIL
[cookieStore.get with absolute url in options]
expected: FAIL
[cookieStore.get with relative url in options]
expected: FAIL
[cookieStore.get with invalid url path in options]
expected: FAIL
[cookieStore.get with invalid url host in options]
expected: FAIL

View File

@ -0,0 +1,8 @@
[cookieStore_get_delete_basic.https.any.serviceworker.html]
[cookieStore.get returns null for a cookie deleted by cookieStore.delete]
expected: FAIL
[cookieStore_get_delete_basic.https.any.html]
[cookieStore.get returns null for a cookie deleted by cookieStore.delete]
expected: FAIL

View File

@ -0,0 +1,6 @@
[cookieStore_get_set_across_frames.https.html]
[cookieStore.get() sees cookieStore.set() in frame]
expected: FAIL
[cookieStore.get() in frame sees cookieStore.set()]
expected: FAIL

View File

@ -0,0 +1,7 @@
[cookieStore_get_set_across_origins.sub.https.html]
expected: TIMEOUT
[cookieStore.get() sees cookieStore.set() in cross-origin frame]
expected: TIMEOUT
[cookieStore.get() in cross-origin frame sees cookieStore.set()]
expected: NOTRUN

View File

@ -0,0 +1,10 @@
[cookieStore_get_set_basic.https.any.html]
[cookieStore.get returns the cookie written by cookieStore.set]
expected: FAIL
[cookieStore_get_set_basic.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[cookieStore.get returns the cookie written by cookieStore.set]
expected: FAIL

View File

@ -0,0 +1,16 @@
[cookieStore_get_set_ordering.https.any.html]
[Set three simple origin session cookies sequentially and ensure they all end up in the cookie jar in order.]
expected: FAIL
[Set three simple origin session cookies in undefined order using Promise.all and ensure they all end up in the cookie jar in any order. ]
expected: FAIL
[cookieStore_get_set_ordering.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[Set three simple origin session cookies sequentially and ensure they all end up in the cookie jar in order.]
expected: FAIL
[Set three simple origin session cookies in undefined order using Promise.all and ensure they all end up in the cookie jar in any order. ]
expected: FAIL

View File

@ -0,0 +1,6 @@
[cookieStore_opaque_origin.https.html]
[cookieStore in non-sandboxed iframe should not throw]
expected: FAIL
[cookieStore in sandboxed iframe should throw SecurityError]
expected: FAIL

View File

@ -1,14 +1,134 @@
[cookieStore_set_arguments.https.any.html]
[cookieStore.set with positional name and value]
expected: FAIL
[cookieStore.set with name and value in options]
expected: FAIL
[cookieStore.set with empty name and an '=' in value]
expected: FAIL
[cookieStore.set with normal name and an '=' in value]
expected: FAIL
[cookieStore.set with expires set to a future Date]
expected: FAIL
[cookieStore.set with expires set to a past Date]
expected: FAIL
[cookieStore.set with expires set to a future timestamp]
expected: FAIL
[cookieStore.set with expires set to a past timestamp]
expected: FAIL
[cookieStore.set domain starts with "."]
expected: FAIL
[cookieStore.set with domain that is not equal current host]
expected: FAIL
[cookieStore.set with domain set to the current hostname]
expected: FAIL
[cookieStore.set with domain set to a subdomain of the current hostname]
expected: FAIL
[cookieStore.set with domain set to a non-domain-matching suffix of the current hostname]
expected: FAIL
[cookieStore.set default domain is null and differs from current hostname]
expected: FAIL
[cookieStore.set with path set to the current directory]
expected: FAIL
[cookieStore.set with path set to a subdirectory of the current directory]
expected: FAIL
[cookieStore.set default path is /]
expected: FAIL
[cookieStore.set adds / to path that does not end with /]
expected: FAIL
[cookieStore.set with path that does not start with /]
expected: FAIL
[cookieStore.set with get result]
expected: FAIL
[cookieStore.set checks if the domain is too long]
expected: FAIL
[cookieStore.set checks if the path is too long]
expected: FAIL
[cookieStore_set_arguments.https.any.serviceworker.html]
[cookieStore.set with positional name and value]
expected: FAIL
[cookieStore.set with name and value in options]
expected: FAIL
[cookieStore.set with empty name and an '=' in value]
expected: FAIL
[cookieStore.set with normal name and an '=' in value]
expected: FAIL
[cookieStore.set with expires set to a future Date]
expected: FAIL
[cookieStore.set with expires set to a past Date]
expected: FAIL
[cookieStore.set with expires set to a future timestamp]
expected: FAIL
[cookieStore.set with expires set to a past timestamp]
expected: FAIL
[cookieStore.set domain starts with "."]
expected: FAIL
[cookieStore.set with domain that is not equal current host]
expected: FAIL
[cookieStore.set with domain set to the current hostname]
expected: FAIL
[cookieStore.set with domain set to a subdomain of the current hostname]
expected: FAIL
[cookieStore.set with domain set to a non-domain-matching suffix of the current hostname]
expected: FAIL
[cookieStore.set default domain is null and differs from current hostname]
expected: FAIL
[cookieStore.set with path set to the current directory]
expected: FAIL
[cookieStore.set with path set to a subdirectory of the current directory]
expected: FAIL
[cookieStore.set default path is /]
expected: FAIL
[cookieStore.set adds / to path that does not end with /]
expected: FAIL
[cookieStore.set with path that does not start with /]
expected: FAIL
[cookieStore.set with get result]
expected: FAIL
[cookieStore.set checks if the domain is too long]
expected: FAIL
[cookieStore.set checks if the path is too long]
expected: FAIL

View File

@ -0,0 +1,56 @@
[cookieStore_special_names.https.any.html]
[cookieStore.set with __Secure- name on secure origin]
expected: FAIL
[cookieStore.set of expired __Secure- cookie name on secure origin]
expected: FAIL
[cookieStore.delete with __Secure- name on secure origin]
expected: FAIL
[cookieStore.set with __Host- name on secure origin]
expected: FAIL
[cookieStore.set of expired __Host- cookie name on secure origin]
expected: FAIL
[cookieStore.delete with __Host- name on secure origin]
expected: FAIL
[cookieStore.set with __Host- prefix and a domain option]
expected: FAIL
[cookieStore.set with __Host- prefix a path option]
expected: FAIL
[cookieStore.set with malformed name.]
expected: FAIL
[cookieStore_special_names.https.any.serviceworker.html]
[cookieStore.set with __Secure- name on secure origin]
expected: FAIL
[cookieStore.set of expired __Secure- cookie name on secure origin]
expected: FAIL
[cookieStore.delete with __Secure- name on secure origin]
expected: FAIL
[cookieStore.set with __Host- name on secure origin]
expected: FAIL
[cookieStore.set of expired __Host- cookie name on secure origin]
expected: FAIL
[cookieStore.delete with __Host- name on secure origin]
expected: FAIL
[cookieStore.set with __Host- prefix and a domain option]
expected: FAIL
[cookieStore.set with __Host- prefix a path option]
expected: FAIL
[cookieStore.set with malformed name.]
expected: FAIL

View File

@ -0,0 +1,16 @@
[encoding.https.any.html]
[BOM not stripped from name]
expected: FAIL
[BOM not stripped from value]
expected: FAIL
[encoding.https.any.serviceworker.html]
expected:
if os == "win": [OK, TIMEOUT]
[BOM not stripped from name]
expected: FAIL
[BOM not stripped from value]
expected: FAIL

View File

@ -0,0 +1,10 @@
[httponly_cookies.https.window.html]
[HttpOnly cookies are not observed]
expected: FAIL
[HttpOnly cookies can not be set by document.cookie]
expected: FAIL
[HttpOnly cookies can not be set by CookieStore]
expected: FAIL

View File

@ -4,6 +4,108 @@
[idlharness.https.any.html]
[CookieStore interface: existence and properties of interface object]
expected: FAIL
[CookieStore interface object length]
expected: FAIL
[CookieStore interface object name]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CookieStore interface: operation get(USVString)]
expected: FAIL
[CookieStore interface: operation get(optional CookieStoreGetOptions)]
expected: FAIL
[CookieStore interface: operation getAll(USVString)]
expected: FAIL
[CookieStore interface: operation getAll(optional CookieStoreGetOptions)]
expected: FAIL
[CookieStore interface: operation set(USVString, USVString)]
expected: FAIL
[CookieStore interface: operation set(CookieInit)]
expected: FAIL
[CookieStore interface: operation delete(USVString)]
expected: FAIL
[CookieStore interface: operation delete(CookieStoreDeleteOptions)]
expected: FAIL
[CookieStore interface: attribute onchange]
expected: FAIL
[CookieStore must be primary interface of self.cookieStore]
expected: FAIL
[Stringification of self.cookieStore]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "get(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling get(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "get(optional CookieStoreGetOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling get(optional CookieStoreGetOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "getAll(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling getAll(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "getAll(optional CookieStoreGetOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling getAll(optional CookieStoreGetOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "set(USVString, USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling set(USVString, USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "set(CookieInit)" with the proper type]
expected: FAIL
[CookieStore interface: calling set(CookieInit) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "delete(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling delete(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "delete(CookieStoreDeleteOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling delete(CookieStoreDeleteOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "onchange" with the proper type]
expected: FAIL
[CookieStoreManager interface: existence and properties of interface object]
expected: FAIL
@ -52,17 +154,155 @@
[CookieStoreManager interface: calling unsubscribe(sequence<CookieStoreGetOptions>) on self.registration.cookies with too few arguments must throw TypeError]
expected: FAIL
[CookieChangeEvent interface: existence and properties of interface object]
expected: FAIL
[CookieChangeEvent interface object length]
expected: FAIL
[CookieChangeEvent interface object name]
expected: FAIL
[CookieChangeEvent interface: existence and properties of interface prototype object]
expected: FAIL
[CookieChangeEvent interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CookieChangeEvent interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CookieChangeEvent interface: attribute changed]
expected: FAIL
[CookieChangeEvent interface: attribute deleted]
expected: FAIL
[CookieChangeEvent must be primary interface of new CookieChangeEvent("change")]
expected: FAIL
[Stringification of new CookieChangeEvent("change")]
expected: FAIL
[CookieChangeEvent interface: new CookieChangeEvent("change") must inherit property "changed" with the proper type]
expected: FAIL
[CookieChangeEvent interface: new CookieChangeEvent("change") must inherit property "deleted" with the proper type]
expected: FAIL
[ServiceWorkerRegistration interface: attribute cookies]
expected: FAIL
[ServiceWorkerRegistration interface: self.registration must inherit property "cookies" with the proper type]
expected: FAIL
[Window interface: attribute cookieStore]
expected: FAIL
[Window interface: self must inherit property "cookieStore" with the proper type]
expected: FAIL
[idlharness.https.any.serviceworker.html]
[CookieStore interface: existence and properties of interface object]
expected: FAIL
[CookieStore interface object length]
expected: FAIL
[CookieStore interface object name]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CookieStore interface: existence and properties of interface prototype object's @@unscopables property]
expected: FAIL
[CookieStore interface: operation get(USVString)]
expected: FAIL
[CookieStore interface: operation get(optional CookieStoreGetOptions)]
expected: FAIL
[CookieStore interface: operation getAll(USVString)]
expected: FAIL
[CookieStore interface: operation getAll(optional CookieStoreGetOptions)]
expected: FAIL
[CookieStore interface: operation set(USVString, USVString)]
expected: FAIL
[CookieStore interface: operation set(CookieInit)]
expected: FAIL
[CookieStore interface: operation delete(USVString)]
expected: FAIL
[CookieStore interface: operation delete(CookieStoreDeleteOptions)]
expected: FAIL
[CookieStore interface: member onchange]
expected: FAIL
[CookieStore must be primary interface of self.cookieStore]
expected: FAIL
[Stringification of self.cookieStore]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "get(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling get(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "get(optional CookieStoreGetOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling get(optional CookieStoreGetOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "getAll(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling getAll(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "getAll(optional CookieStoreGetOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling getAll(optional CookieStoreGetOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "set(USVString, USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling set(USVString, USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "set(CookieInit)" with the proper type]
expected: FAIL
[CookieStore interface: calling set(CookieInit) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "delete(USVString)" with the proper type]
expected: FAIL
[CookieStore interface: calling delete(USVString) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must inherit property "delete(CookieStoreDeleteOptions)" with the proper type]
expected: FAIL
[CookieStore interface: calling delete(CookieStoreDeleteOptions) on self.cookieStore with too few arguments must throw TypeError]
expected: FAIL
[CookieStore interface: self.cookieStore must not have property "onchange"]
expected: FAIL
@ -156,9 +396,15 @@
[ServiceWorkerRegistration interface: self.registration must inherit property "cookies" with the proper type]
expected: FAIL
[ServiceWorkerGlobalScope interface: attribute cookieStore]
expected: FAIL
[ServiceWorkerGlobalScope interface: attribute oncookiechange]
expected: FAIL
[ServiceWorkerGlobalScope interface: self must inherit property "cookieStore" with the proper type]
expected: FAIL
[ServiceWorkerGlobalScope interface: self must inherit property "oncookiechange" with the proper type]
expected: FAIL

View File

@ -0,0 +1,4 @@
[serviceworker_cookieStore_cross_origin.https.sub.html]
expected: TIMEOUT
[cookieStore.get() in ServiceWorker reads cookie set in cross-origin frame]
expected: TIMEOUT

View File

@ -48,9 +48,6 @@ with Files("mozilla/README"):
with Files("mozilla/meta/**"):
BUG_COMPONENT = ("Testing", "web-platform-tests")
with Files("mozilla/tests/cookie-store/**"):
BUG_COMPONENT = ("Core", "DOM: Networking")
with Files("mozilla/tests/dom/**"):
BUG_COMPONENT = ("Core", "DOM: Core & HTML")

View File

@ -1 +0,0 @@
prefs: [dom.cookieStore.enabled:true]

View File

@ -1,44 +0,0 @@
// META: title=CookieStore queues events when bfcached
// META: script=/common/dispatcher/dispatcher.js
// META: script=/common/utils.js
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js
'use strict';
promise_test(async t => {
const rcHelper = new RemoteContextHelper();
// Open a window with noopener so that BFCache will work.
const rc = await rcHelper.addWindow(null, { features: "noopener" });
await rc.executeScript(() => {
window.events = [];
window.addEventListener('pageshow', (event) => {
window.events.push("pageshow:" + event.persisted);
});
window.cookiePromise = new Promise(resolve => {
cookieStore.addEventListener('change', () => {
window.events.push("cookie");
resolve();
}, {once: true});
});
});
const rc2 = await rc.navigateToNew();
await rc2.executeScript(() => {
document.cookie = "BFCACHE=1; path=/";
});
await rc2.historyBack();
assert_equals(
await rc.executeScript(async () => window.cookiePromise.then(() => window.events.join("-"))), "pageshow:true-cookie",
'precondition: document was bfcached'
);
await rc.executeScript(async () => {
await cookieStore.delete("BFCACHE");
});
});

View File

@ -147,39 +147,3 @@ promise_test(async testCase => {
await promise_rejects_js(testCase, TypeError, cookieStore.getAll(
{ url: invalid_url }));
}, 'cookieStore.getAll with invalid url host in options');
promise_test(async testCase => {
await cookieStore.set('cookie-name', 'cookie-value');
testCase.add_cleanup(async () => {
await cookieStore.delete('cookie-name');
});
let target_url = self.location.href;
if (self.GLOBAL.isWorker()) {
target_url = target_url + '/path/within/scope';
}
target_url = target_url + "#foo";
const cookies = await cookieStore.getAll({ url: target_url });
assert_equals(cookies.length, 1);
assert_equals(cookies[0].name, 'cookie-name');
assert_equals(cookies[0].value, 'cookie-value');
}, 'cookieStore.getAll with absolute url with fragment in options');
promise_test(async testCase => {
if (!self.GLOBAL.isWorker()) {
await cookieStore.set('cookie-name', 'cookie-value');
testCase.add_cleanup(async () => {
await cookieStore.delete('cookie-name');
});
self.location = "#foo";
let target_url = self.location.href;
const cookies = await cookieStore.getAll({ url: target_url });
assert_equals(cookies.length, 1);
assert_equals(cookies[0].name, 'cookie-name');
assert_equals(cookies[0].value, 'cookie-value');
}
}, 'cookieStore.getAll with absolute different url in options');

View File

@ -100,37 +100,3 @@ promise_test(async testCase => {
await promise_rejects_js(testCase, TypeError, cookieStore.get(
{ url: invalid_url }));
}, 'cookieStore.get with invalid url host in options');
promise_test(async testCase => {
await cookieStore.set('cookie-name', 'cookie-value');
testCase.add_cleanup(async () => {
await cookieStore.delete('cookie-name');
});
let target_url = self.location.href;
if (self.GLOBAL.isWorker()) {
target_url = target_url + '/path/within/scope';
}
target_url = target_url + "#foo";
const cookie = await cookieStore.get({ url: target_url });
assert_equals(cookie.name, 'cookie-name');
assert_equals(cookie.value, 'cookie-value');
}, 'cookieStore.get with absolute url with fragment in options');
promise_test(async testCase => {
if (!self.GLOBAL.isWorker()) {
await cookieStore.set('cookie-name', 'cookie-value');
testCase.add_cleanup(async () => {
await cookieStore.delete('cookie-name');
});
self.location = "#foo";
let target_url = self.location.href;
const cookie = await cookieStore.get({ url: target_url });
assert_equals(cookie.name, 'cookie-name');
assert_equals(cookie.value, 'cookie-value');
}
}, 'cookieStore.get with absolute different url in options');

View File

@ -1,86 +0,0 @@
<!doctype html>
<meta charset='utf-8'>
<title>Async Cookies: cookieStore basic API on creation URL with fragments</title>
<link rel='help' href='https://github.com/WICG/cookie-store'>
<link rel='author' href='baku@mozilla.com' title='Andrea Marchesini'>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='resources/helpers.js'></script>
<style>iframe { display: none; }</style>
<script>
'use strict';
const kUrl = '/cookie-store/resources/helper_iframe.sub.html';
promise_test(async t => {
const url = new URL(kUrl, location);
const iframe = await createIframe(url + "#fragment", t);
assert_true(iframe != null);
iframe.contentWindow.postMessage({
opname: 'set-cookie',
name: 'cookie-name',
value: 'cookie-value',
}, '*');
t.add_cleanup(async () => {
await cookieStore.delete({ name: 'cookie-name', domain: '{{host}}' });
});
await waitForMessage();
iframe.contentWindow.postMessage({
opname: 'get-cookie',
name: 'cookie-name',
options: { url: url.href }
}, '*');
const message = await waitForMessage();
const { frameCookie } = message;
assert_not_equals(frameCookie, null);
assert_equals(frameCookie.name, 'cookie-name');
assert_equals(frameCookie.value, 'cookie-value');
}, 'cookieStore.get() option url ignores fragments');
promise_test(async t => {
const url = new URL(kUrl, location);
const iframe = await createIframe(url + "#fragment", t);
assert_true(iframe != null);
iframe.contentWindow.postMessage({
opname: 'set-cookie',
name: 'cookie-name',
value: 'cookie-value',
}, '*');
t.add_cleanup(async () => {
await cookieStore.delete({ name: 'cookie-name', domain: '{{host}}' });
});
await waitForMessage();
iframe.contentWindow.postMessage({
opname: 'push-state',
}, '*');
await waitForMessage();
iframe.contentWindow.postMessage({
opname: 'get-cookie',
name: 'cookie-name',
options: { url: url.href }
}, '*');
const message = await waitForMessage();
const { frameCookie } = message;
assert_not_equals(frameCookie, null);
assert_equals(frameCookie.name, 'cookie-name');
assert_equals(frameCookie.value, 'cookie-value');
}, 'cookieStore.get() option url + pushState()');
</script>

View File

@ -23,12 +23,9 @@
});
event.source.postMessage('Cookie has been set', event.origin);
} else if (opname === 'get-cookie') {
const { name, options } = event.data
const frameCookie = await cookieStore.get(name, options);
const { name } = event.data
const frameCookie = await cookieStore.get(name);
event.source.postMessage({frameCookie}, event.origin);
} else if (opname === 'push-state') {
history.pushState("foo", null, "some/path");
event.source.postMessage('pushState called');
}
});
</script>

View File

@ -326,8 +326,7 @@ nsresult nsCookieInjector::InjectCookiesFromRules(
rv = cookieManager->AddNative(
c.Host(), c.Path(), c.Name(), c.Value(), c.IsSecure(), c.IsHttpOnly(),
c.IsSession(), c.Expiry(), &aOriginAttributes, c.SameSite(),
static_cast<nsICookie::schemeType>(c.SchemeMap()),
/* is partitioned: */ false, nullptr);
static_cast<nsICookie::schemeType>(c.SchemeMap()));
NS_ENSURE_SUCCESS(rv, rv);
aHasInjectedCookie = true;

View File

@ -800,7 +800,6 @@ STATIC_ATOMS = [
Atom("oncontextmenu", "oncontextmenu"),
Atom("oncontextlost", "oncontextlost"),
Atom("oncontextrestored", "oncontextrestored"),
Atom("oncookiechange", "oncookiechange"),
Atom("oncopy", "oncopy"),
Atom("oncut", "oncut"),
Atom("oncurrententrychange", "oncurrententrychange"),