1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozIThirdPartyUtil.h"
8 #include "mozilla/AntiTrackingUtils.h"
9 #include "mozilla/BasePrincipal.h"
10 #include "mozilla/ClearOnShutdown.h"
11 #include "mozilla/Components.h"
12 #include "mozilla/ContentBlockingAllowList.h"
13 #include "mozilla/dom/BrowsingContext.h"
14 #include "mozilla/net/CookieJarSettings.h"
15 #include "mozilla/net/NeckoChannelParams.h"
16 #include "mozilla/Permission.h"
17 #include "mozilla/PermissionManager.h"
18 #include "mozilla/SchedulerGroup.h"
19 #include "mozilla/StaticPrefs_network.h"
20 #include "mozilla/StoragePrincipalHelper.h"
21 #include "mozilla/Unused.h"
22 #include "nsIPrincipal.h"
23 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
24 # include "nsIProtocolHandler.h"
26 #include "nsIClassInfoImpl.h"
27 #include "nsIChannel.h"
28 #include "nsICookieManager.h"
29 #include "nsICookieService.h"
30 #include "nsIObjectInputStream.h"
31 #include "nsIObjectOutputStream.h"
32 #include "nsNetUtil.h"
37 NS_IMPL_CLASSINFO(CookieJarSettings
, nullptr, nsIClassInfo::THREADSAFE
,
38 COOKIEJARSETTINGS_CID
)
40 NS_IMPL_ISUPPORTS_CI(CookieJarSettings
, nsICookieJarSettings
, nsISerializable
)
42 static StaticRefPtr
<CookieJarSettings
> sBlockinAll
;
46 class PermissionComparator
{
48 static bool Equals(nsIPermission
* aA
, nsIPermission
* aB
) {
49 nsCOMPtr
<nsIPrincipal
> principalA
;
50 nsresult rv
= aA
->GetPrincipal(getter_AddRefs(principalA
));
51 if (NS_WARN_IF(NS_FAILED(rv
))) {
55 nsCOMPtr
<nsIPrincipal
> principalB
;
56 rv
= aB
->GetPrincipal(getter_AddRefs(principalB
));
57 if (NS_WARN_IF(NS_FAILED(rv
))) {
62 rv
= principalA
->Equals(principalB
, &equals
);
63 if (NS_WARN_IF(NS_FAILED(rv
))) {
71 class ReleaseCookiePermissions final
: public Runnable
{
73 explicit ReleaseCookiePermissions(nsTArray
<RefPtr
<nsIPermission
>>&& aArray
)
74 : Runnable("ReleaseCookiePermissions"), mArray(std::move(aArray
)) {}
76 NS_IMETHOD
Run() override
{
77 MOZ_ASSERT(NS_IsMainThread());
83 nsTArray
<RefPtr
<nsIPermission
>> mArray
;
89 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::GetBlockingAll(
90 bool aShouldResistFingerprinting
) {
91 MOZ_ASSERT(NS_IsMainThread());
94 return do_AddRef(sBlockinAll
);
97 sBlockinAll
= new CookieJarSettings(nsICookieService::BEHAVIOR_REJECT
,
98 OriginAttributes::IsFirstPartyEnabled(),
99 aShouldResistFingerprinting
, eFixed
);
100 ClearOnShutdown(&sBlockinAll
);
102 return do_AddRef(sBlockinAll
);
106 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
107 CreateMode aMode
, bool aShouldResistFingerprinting
) {
108 MOZ_ASSERT(NS_IsMainThread());
110 RefPtr
<CookieJarSettings
> cookieJarSettings
;
115 cookieJarSettings
= new CookieJarSettings(
116 nsICookieManager::GetCookieBehavior(aMode
== ePrivate
),
117 OriginAttributes::IsFirstPartyEnabled(), aShouldResistFingerprinting
,
122 MOZ_CRASH("Unexpected create mode.");
125 return cookieJarSettings
.forget();
129 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
130 nsIPrincipal
* aPrincipal
) {
131 MOZ_ASSERT(NS_IsMainThread());
133 bool shouldResistFingerprinting
=
134 nsContentUtils::ShouldResistFingerprinting_dangerous(
135 aPrincipal
, "We are constructing CookieJarSettings here.",
136 RFPTarget::IsAlwaysEnabledForPrecompute
);
138 if (aPrincipal
&& aPrincipal
->OriginAttributesRef().mPrivateBrowsingId
> 0) {
139 return Create(ePrivate
, shouldResistFingerprinting
);
142 return Create(eRegular
, shouldResistFingerprinting
);
146 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
147 uint32_t aCookieBehavior
, const nsAString
& aPartitionKey
,
148 bool aIsFirstPartyIsolated
, bool aIsOnContentBlockingAllowList
,
149 bool aShouldResistFingerprinting
) {
150 MOZ_ASSERT(NS_IsMainThread());
152 RefPtr
<CookieJarSettings
> cookieJarSettings
=
153 new CookieJarSettings(aCookieBehavior
, aIsFirstPartyIsolated
,
154 aShouldResistFingerprinting
, eProgressive
);
155 cookieJarSettings
->mPartitionKey
= aPartitionKey
;
156 cookieJarSettings
->mIsOnContentBlockingAllowList
=
157 aIsOnContentBlockingAllowList
;
159 return cookieJarSettings
.forget();
163 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::CreateForXPCOM() {
164 MOZ_ASSERT(NS_IsMainThread());
165 return Create(eRegular
, /* shouldResistFingerprinting */ false);
168 CookieJarSettings::CookieJarSettings(uint32_t aCookieBehavior
,
169 bool aIsFirstPartyIsolated
,
170 bool aShouldResistFingerprinting
,
172 : mCookieBehavior(aCookieBehavior
),
173 mIsFirstPartyIsolated(aIsFirstPartyIsolated
),
174 mIsOnContentBlockingAllowList(false),
175 mIsOnContentBlockingAllowListUpdated(false),
178 mShouldResistFingerprinting(aShouldResistFingerprinting
),
179 mTopLevelWindowContextId(0) {
180 MOZ_ASSERT(NS_IsMainThread());
182 mIsFirstPartyIsolated
,
184 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
187 CookieJarSettings::~CookieJarSettings() {
188 if (!NS_IsMainThread() && !mCookiePermissions
.IsEmpty()) {
190 new ReleaseCookiePermissions(std::move(mCookiePermissions
));
191 MOZ_ASSERT(mCookiePermissions
.IsEmpty());
192 SchedulerGroup::Dispatch(r
.forget());
197 CookieJarSettings::InitWithURI(nsIURI
* aURI
, bool aIsPrivate
) {
200 mCookieBehavior
= nsICookieManager::GetCookieBehavior(aIsPrivate
);
202 SetPartitionKey(aURI
, false);
207 CookieJarSettings::GetCookieBehavior(uint32_t* aCookieBehavior
) {
208 *aCookieBehavior
= mCookieBehavior
;
213 CookieJarSettings::GetIsFirstPartyIsolated(bool* aIsFirstPartyIsolated
) {
214 *aIsFirstPartyIsolated
= mIsFirstPartyIsolated
;
219 CookieJarSettings::GetShouldResistFingerprinting(
220 bool* aShouldResistFingerprinting
) {
221 *aShouldResistFingerprinting
= mShouldResistFingerprinting
;
226 CookieJarSettings::GetRejectThirdPartyContexts(
227 bool* aRejectThirdPartyContexts
) {
228 *aRejectThirdPartyContexts
=
229 CookieJarSettings::IsRejectThirdPartyContexts(mCookieBehavior
);
234 CookieJarSettings::GetLimitForeignContexts(bool* aLimitForeignContexts
) {
235 *aLimitForeignContexts
=
236 mCookieBehavior
== nsICookieService::BEHAVIOR_LIMIT_FOREIGN
||
237 (StaticPrefs::privacy_dynamic_firstparty_limitForeign() &&
239 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
244 CookieJarSettings::GetBlockingAllThirdPartyContexts(
245 bool* aBlockingAllThirdPartyContexts
) {
246 // XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
247 // simply rejecting the request to use the storage. In the future, if we
248 // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
249 // for non-cookie storage types, this may change.
250 *aBlockingAllThirdPartyContexts
=
251 mCookieBehavior
== nsICookieService::BEHAVIOR_LIMIT_FOREIGN
||
252 mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_FOREIGN
;
257 CookieJarSettings::GetBlockingAllContexts(bool* aBlockingAllContexts
) {
258 *aBlockingAllContexts
= mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT
;
263 CookieJarSettings::GetPartitionForeign(bool* aPartitionForeign
) {
266 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
271 CookieJarSettings::SetPartitionForeign(bool aPartitionForeign
) {
272 if (mIsFirstPartyIsolated
) {
276 if (aPartitionForeign
) {
278 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
284 CookieJarSettings::GetIsOnContentBlockingAllowList(
285 bool* aIsOnContentBlockingAllowList
) {
286 *aIsOnContentBlockingAllowList
= mIsOnContentBlockingAllowList
;
291 CookieJarSettings::GetPartitionKey(nsAString
& aPartitionKey
) {
292 aPartitionKey
= mPartitionKey
;
297 CookieJarSettings::GetFingerprintingRandomizationKey(
298 nsTArray
<uint8_t>& aFingerprintingRandomizationKey
) {
299 if (!mFingerprintingRandomKey
) {
300 return NS_ERROR_NOT_AVAILABLE
;
303 aFingerprintingRandomizationKey
= mFingerprintingRandomKey
->Clone();
308 CookieJarSettings::CookiePermission(nsIPrincipal
* aPrincipal
,
309 uint32_t* aCookiePermission
) {
310 MOZ_RELEASE_ASSERT(NS_IsMainThread());
311 NS_ENSURE_ARG_POINTER(aPrincipal
);
312 NS_ENSURE_ARG_POINTER(aCookiePermission
);
314 *aCookiePermission
= nsIPermissionManager::UNKNOWN_ACTION
;
318 // Let's see if we know this permission.
319 if (!mCookiePermissions
.IsEmpty()) {
320 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
322 rv
= permission
->Matches(aPrincipal
, false, &match
);
323 if (NS_WARN_IF(NS_FAILED(rv
)) || !match
) {
327 rv
= permission
->GetCapability(aCookiePermission
);
328 if (NS_WARN_IF(NS_FAILED(rv
))) {
336 // Let's ask the permission manager.
337 PermissionManager
* pm
= PermissionManager::GetInstance();
338 if (NS_WARN_IF(!pm
)) {
339 return NS_ERROR_FAILURE
;
342 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
343 // Check if this protocol doesn't allow cookies.
345 nsCOMPtr
<nsIURI
> uri
;
346 BasePrincipal::Cast(aPrincipal
)->GetURI(getter_AddRefs(uri
));
348 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_FORBIDS_COOKIE_ACCESS
,
350 if (NS_FAILED(rv
) || hasFlags
) {
351 *aCookiePermission
= PermissionManager::DENY_ACTION
;
352 rv
= NS_OK
; // Reset, so it's not caught as a bad status after the `else`.
353 } else // Note the tricky `else` which controls the call below.
356 rv
= pm
->TestPermissionFromPrincipal(aPrincipal
, "cookie"_ns
,
358 if (NS_WARN_IF(NS_FAILED(rv
))) {
362 // Let's store the permission, also if the result is UNKNOWN in order to avoid
365 nsCOMPtr
<nsIPermission
> permission
=
366 Permission::Create(aPrincipal
, "cookie"_ns
, *aCookiePermission
, 0, 0, 0);
368 mCookiePermissions
.AppendElement(permission
);
375 void CookieJarSettings::Serialize(CookieJarSettingsArgs
& aData
) {
376 MOZ_RELEASE_ASSERT(NS_IsMainThread());
378 aData
.isFixed() = mState
== eFixed
;
379 aData
.cookieBehavior() = mCookieBehavior
;
380 aData
.isFirstPartyIsolated() = mIsFirstPartyIsolated
;
381 aData
.shouldResistFingerprinting() = mShouldResistFingerprinting
;
382 aData
.isOnContentBlockingAllowList() = mIsOnContentBlockingAllowList
;
383 aData
.partitionKey() = mPartitionKey
;
384 if (mFingerprintingRandomKey
) {
385 aData
.hasFingerprintingRandomizationKey() = true;
386 aData
.fingerprintingRandomizationKey() = mFingerprintingRandomKey
->Clone();
388 aData
.hasFingerprintingRandomizationKey() = false;
391 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
392 nsCOMPtr
<nsIPrincipal
> principal
;
393 nsresult rv
= permission
->GetPrincipal(getter_AddRefs(principal
));
394 if (NS_WARN_IF(NS_FAILED(rv
))) {
398 ipc::PrincipalInfo principalInfo
;
399 rv
= PrincipalToPrincipalInfo(principal
, &principalInfo
,
400 true /* aSkipBaseDomain */);
401 if (NS_WARN_IF(NS_FAILED(rv
))) {
405 uint32_t cookiePermission
= 0;
406 rv
= permission
->GetCapability(&cookiePermission
);
407 if (NS_WARN_IF(NS_FAILED(rv
))) {
411 aData
.cookiePermissions().AppendElement(
412 CookiePermissionData(principalInfo
, cookiePermission
));
415 aData
.topLevelWindowContextId() = mTopLevelWindowContextId
;
420 /* static */ void CookieJarSettings::Deserialize(
421 const CookieJarSettingsArgs
& aData
,
422 nsICookieJarSettings
** aCookieJarSettings
) {
423 MOZ_RELEASE_ASSERT(NS_IsMainThread());
425 CookiePermissionList list
;
426 for (const CookiePermissionData
& data
: aData
.cookiePermissions()) {
427 auto principalOrErr
= PrincipalInfoToPrincipal(data
.principalInfo());
428 if (NS_WARN_IF(principalOrErr
.isErr())) {
432 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
434 nsCOMPtr
<nsIPermission
> permission
= Permission::Create(
435 principal
, "cookie"_ns
, data
.cookiePermission(), 0, 0, 0);
436 if (NS_WARN_IF(!permission
)) {
440 list
.AppendElement(permission
);
443 RefPtr
<CookieJarSettings
> cookieJarSettings
= new CookieJarSettings(
444 aData
.cookieBehavior(), aData
.isFirstPartyIsolated(),
445 aData
.shouldResistFingerprinting(),
446 aData
.isFixed() ? eFixed
: eProgressive
);
448 cookieJarSettings
->mIsOnContentBlockingAllowList
=
449 aData
.isOnContentBlockingAllowList();
450 cookieJarSettings
->mCookiePermissions
= std::move(list
);
451 cookieJarSettings
->mPartitionKey
= aData
.partitionKey();
452 cookieJarSettings
->mShouldResistFingerprinting
=
453 aData
.shouldResistFingerprinting();
455 if (aData
.hasFingerprintingRandomizationKey()) {
456 cookieJarSettings
->mFingerprintingRandomKey
.emplace(
457 aData
.fingerprintingRandomizationKey().Clone());
460 cookieJarSettings
->mTopLevelWindowContextId
= aData
.topLevelWindowContextId();
462 cookieJarSettings
.forget(aCookieJarSettings
);
465 void CookieJarSettings::Merge(const CookieJarSettingsArgs
& aData
) {
466 MOZ_RELEASE_ASSERT(NS_IsMainThread());
468 mCookieBehavior
== aData
.cookieBehavior() ||
469 (mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
470 aData
.cookieBehavior() ==
471 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) ||
473 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
474 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
));
476 if (mState
== eFixed
) {
480 // Merge cookie behavior pref values
481 if (mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
482 aData
.cookieBehavior() ==
483 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) {
484 // If the other side has decided to partition third-party cookies, update
485 // our side when first-party isolation is disabled.
486 if (!mIsFirstPartyIsolated
) {
488 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
491 if (mCookieBehavior
==
492 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
493 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
) {
494 // If we've decided to partition third-party cookies, the other side may not
495 // have caught up yet unless it has first-party isolation enabled.
496 if (aData
.isFirstPartyIsolated()) {
497 mCookieBehavior
= nsICookieService::BEHAVIOR_REJECT_TRACKER
;
498 mIsFirstPartyIsolated
= true;
501 // Ignore all other cases.
503 mIsFirstPartyIsolated
,
505 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
507 if (aData
.shouldResistFingerprinting()) {
508 mShouldResistFingerprinting
= true;
511 PermissionComparator comparator
;
513 for (const CookiePermissionData
& data
: aData
.cookiePermissions()) {
514 auto principalOrErr
= PrincipalInfoToPrincipal(data
.principalInfo());
515 if (NS_WARN_IF(principalOrErr
.isErr())) {
519 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
520 nsCOMPtr
<nsIPermission
> permission
= Permission::Create(
521 principal
, "cookie"_ns
, data
.cookiePermission(), 0, 0, 0);
522 if (NS_WARN_IF(!permission
)) {
526 if (!mCookiePermissions
.Contains(permission
, comparator
)) {
527 mCookiePermissions
.AppendElement(permission
);
532 void CookieJarSettings::SetPartitionKey(nsIURI
* aURI
,
533 bool aForeignByAncestorContext
) {
536 OriginAttributes attrs
;
537 attrs
.SetPartitionKey(aURI
, aForeignByAncestorContext
);
538 mPartitionKey
= std::move(attrs
.mPartitionKey
);
541 void CookieJarSettings::UpdatePartitionKeyForDocumentLoadedByChannel(
542 nsIChannel
* aChannel
) {
543 nsCOMPtr
<nsILoadInfo
> loadInfo
= aChannel
->LoadInfo();
544 bool thirdParty
= AntiTrackingUtils::IsThirdPartyChannel(aChannel
);
545 bool foreignByAncestorContext
=
546 thirdParty
&& !loadInfo
->GetIsThirdPartyContextToTopWindow();
547 StoragePrincipalHelper::UpdatePartitionKeyWithForeignAncestorBit(
548 mPartitionKey
, foreignByAncestorContext
);
551 void CookieJarSettings::UpdateIsOnContentBlockingAllowList(
552 nsIChannel
* aChannel
) {
553 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
554 MOZ_ASSERT(aChannel
);
556 // Early return if the flag was updated before.
557 if (mIsOnContentBlockingAllowListUpdated
) {
560 mIsOnContentBlockingAllowListUpdated
= true;
562 nsCOMPtr
<nsILoadInfo
> loadInfo
= aChannel
->LoadInfo();
564 nsCOMPtr
<nsIURI
> uri
;
565 nsresult rv
= aChannel
->GetURI(getter_AddRefs(uri
));
566 if (NS_WARN_IF(NS_FAILED(rv
))) {
570 // We need to recompute the ContentBlockingAllowListPrincipal here for the
571 // top level channel because we might navigate from the the initial
572 // about:blank page or the existing page which may have a different origin
573 // than the URI we are going to load here. Thus, we need to recompute the
574 // prinicpal in order to get the correct ContentBlockingAllowListPrincipal.
575 nsCOMPtr
<nsIPrincipal
> contentBlockingAllowListPrincipal
;
576 OriginAttributes attrs
;
577 loadInfo
->GetOriginAttributes(&attrs
);
578 ContentBlockingAllowList::RecomputePrincipal(
579 uri
, attrs
, getter_AddRefs(contentBlockingAllowListPrincipal
));
581 if (!contentBlockingAllowListPrincipal
||
582 !contentBlockingAllowListPrincipal
->GetIsContentPrincipal()) {
586 Unused
<< ContentBlockingAllowList::Check(contentBlockingAllowListPrincipal
,
587 NS_UsePrivateBrowsing(aChannel
),
588 mIsOnContentBlockingAllowList
);
592 bool CookieJarSettings::IsRejectThirdPartyContexts(uint32_t aCookieBehavior
) {
593 return aCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
||
595 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
599 CookieJarSettings::Read(nsIObjectInputStream
* aStream
) {
600 MOZ_RELEASE_ASSERT(NS_IsMainThread());
601 nsresult rv
= aStream
->Read32(&mCookieBehavior
);
602 if (NS_WARN_IF(NS_FAILED(rv
))) {
606 rv
= aStream
->ReadBoolean(&mIsFirstPartyIsolated
);
607 if (NS_WARN_IF(NS_FAILED(rv
))) {
611 rv
= aStream
->ReadBoolean(&mShouldResistFingerprinting
);
612 if (NS_WARN_IF(NS_FAILED(rv
))) {
617 aStream
->ReadBoolean(&isFixed
);
618 if (NS_WARN_IF(NS_FAILED(rv
))) {
621 mState
= isFixed
? eFixed
: eProgressive
;
623 rv
= aStream
->ReadBoolean(&mIsOnContentBlockingAllowList
);
624 if (NS_WARN_IF(NS_FAILED(rv
))) {
628 rv
= aStream
->ReadString(mPartitionKey
);
629 if (NS_WARN_IF(NS_FAILED(rv
))) {
633 // Deserializing the cookie permission list.
634 uint32_t cookiePermissionsLength
;
635 rv
= aStream
->Read32(&cookiePermissionsLength
);
636 if (NS_WARN_IF(NS_FAILED(rv
))) {
640 if (!cookiePermissionsLength
) {
641 // Bailing out early because there is no cookie permission.
645 CookiePermissionList list
;
646 mCookiePermissions
.SetCapacity(cookiePermissionsLength
);
647 for (uint32_t i
= 0; i
< cookiePermissionsLength
; ++i
) {
648 nsAutoCString principalJSON
;
649 aStream
->ReadCString(principalJSON
);
650 if (NS_WARN_IF(NS_FAILED(rv
))) {
654 nsCOMPtr
<nsIPrincipal
> principal
= BasePrincipal::FromJSON(principalJSON
);
656 if (NS_WARN_IF(!principal
)) {
660 uint32_t cookiePermission
;
661 aStream
->Read32(&cookiePermission
);
662 if (NS_WARN_IF(NS_FAILED(rv
))) {
666 nsCOMPtr
<nsIPermission
> permission
=
667 Permission::Create(principal
, "cookie"_ns
, cookiePermission
, 0, 0, 0);
668 if (NS_WARN_IF(!permission
)) {
672 list
.AppendElement(permission
);
675 mCookiePermissions
= std::move(list
);
681 CookieJarSettings::Write(nsIObjectOutputStream
* aStream
) {
682 MOZ_RELEASE_ASSERT(NS_IsMainThread());
683 nsresult rv
= aStream
->Write32(mCookieBehavior
);
684 if (NS_WARN_IF(NS_FAILED(rv
))) {
688 rv
= aStream
->WriteBoolean(mIsFirstPartyIsolated
);
689 if (NS_WARN_IF(NS_FAILED(rv
))) {
693 rv
= aStream
->WriteBoolean(mShouldResistFingerprinting
);
694 if (NS_WARN_IF(NS_FAILED(rv
))) {
698 rv
= aStream
->WriteBoolean(mState
== eFixed
);
699 if (NS_WARN_IF(NS_FAILED(rv
))) {
703 rv
= aStream
->WriteBoolean(mIsOnContentBlockingAllowList
);
704 if (NS_WARN_IF(NS_FAILED(rv
))) {
708 rv
= aStream
->WriteWStringZ(mPartitionKey
.get());
709 if (NS_WARN_IF(NS_FAILED(rv
))) {
713 // Serializing the cookie permission list. It will first write the length of
714 // the list, and then, write the cookie permission consecutively.
715 uint32_t cookiePermissionsLength
= mCookiePermissions
.Length();
716 rv
= aStream
->Write32(cookiePermissionsLength
);
717 if (NS_WARN_IF(NS_FAILED(rv
))) {
721 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
722 nsCOMPtr
<nsIPrincipal
> principal
;
723 nsresult rv
= permission
->GetPrincipal(getter_AddRefs(principal
));
724 if (NS_WARN_IF(NS_FAILED(rv
))) {
728 nsAutoCString principalJSON
;
729 BasePrincipal::Cast(principal
)->ToJSON(principalJSON
);
731 rv
= aStream
->WriteStringZ(principalJSON
.get());
732 if (NS_WARN_IF(NS_FAILED(rv
))) {
736 uint32_t cookiePermission
= 0;
737 rv
= permission
->GetCapability(&cookiePermission
);
738 if (NS_WARN_IF(NS_FAILED(rv
))) {
742 rv
= aStream
->Write32(cookiePermission
);
743 if (NS_WARN_IF(NS_FAILED(rv
))) {
752 } // namespace mozilla