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 "mozilla/AntiTrackingUtils.h"
8 #include "mozilla/BasePrincipal.h"
9 #include "mozilla/ClearOnShutdown.h"
10 #include "mozilla/ContentBlockingAllowList.h"
11 #include "mozilla/dom/BrowsingContext.h"
12 #include "mozilla/net/CookieJarSettings.h"
13 #include "mozilla/net/NeckoChannelParams.h"
14 #include "mozilla/Permission.h"
15 #include "mozilla/PermissionManager.h"
16 #include "mozilla/SchedulerGroup.h"
17 #include "mozilla/StaticPrefs_network.h"
18 #include "mozilla/Unused.h"
19 #include "nsIPrincipal.h"
20 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
21 # include "nsIProtocolHandler.h"
23 #include "nsIClassInfoImpl.h"
24 #include "nsIChannel.h"
25 #include "nsICookieManager.h"
26 #include "nsICookieService.h"
27 #include "nsIObjectInputStream.h"
28 #include "nsIObjectOutputStream.h"
29 #include "nsNetUtil.h"
34 NS_IMPL_CLASSINFO(CookieJarSettings
, nullptr, nsIClassInfo::THREADSAFE
,
35 COOKIEJARSETTINGS_CID
)
37 NS_IMPL_ISUPPORTS_CI(CookieJarSettings
, nsICookieJarSettings
, nsISerializable
)
39 static StaticRefPtr
<CookieJarSettings
> sBlockinAll
;
43 class PermissionComparator
{
45 static bool Equals(nsIPermission
* aA
, nsIPermission
* aB
) {
46 nsCOMPtr
<nsIPrincipal
> principalA
;
47 nsresult rv
= aA
->GetPrincipal(getter_AddRefs(principalA
));
48 if (NS_WARN_IF(NS_FAILED(rv
))) {
52 nsCOMPtr
<nsIPrincipal
> principalB
;
53 rv
= aB
->GetPrincipal(getter_AddRefs(principalB
));
54 if (NS_WARN_IF(NS_FAILED(rv
))) {
59 rv
= principalA
->Equals(principalB
, &equals
);
60 if (NS_WARN_IF(NS_FAILED(rv
))) {
68 class ReleaseCookiePermissions final
: public Runnable
{
70 explicit ReleaseCookiePermissions(nsTArray
<RefPtr
<nsIPermission
>>&& aArray
)
71 : Runnable("ReleaseCookiePermissions"), mArray(std::move(aArray
)) {}
73 NS_IMETHOD
Run() override
{
74 MOZ_ASSERT(NS_IsMainThread());
80 nsTArray
<RefPtr
<nsIPermission
>> mArray
;
86 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::GetBlockingAll(
87 bool aShouldResistFingerprinting
) {
88 MOZ_ASSERT(NS_IsMainThread());
91 return do_AddRef(sBlockinAll
);
94 sBlockinAll
= new CookieJarSettings(nsICookieService::BEHAVIOR_REJECT
,
95 OriginAttributes::IsFirstPartyEnabled(),
96 aShouldResistFingerprinting
, eFixed
);
97 ClearOnShutdown(&sBlockinAll
);
99 return do_AddRef(sBlockinAll
);
103 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
104 CreateMode aMode
, bool aShouldResistFingerprinting
) {
105 MOZ_ASSERT(NS_IsMainThread());
107 RefPtr
<CookieJarSettings
> cookieJarSettings
;
112 cookieJarSettings
= new CookieJarSettings(
113 nsICookieManager::GetCookieBehavior(aMode
== ePrivate
),
114 OriginAttributes::IsFirstPartyEnabled(), aShouldResistFingerprinting
,
119 MOZ_CRASH("Unexpected create mode.");
122 return cookieJarSettings
.forget();
126 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
127 nsIPrincipal
* aPrincipal
) {
128 MOZ_ASSERT(NS_IsMainThread());
130 bool shouldResistFingerprinting
=
131 nsContentUtils::ShouldResistFingerprinting_dangerous(
132 aPrincipal
, "We are constructing CookieJarSettings here.",
133 RFPTarget::IsAlwaysEnabledForPrecompute
);
135 if (aPrincipal
&& aPrincipal
->OriginAttributesRef().mPrivateBrowsingId
> 0) {
136 return Create(ePrivate
, shouldResistFingerprinting
);
139 return Create(eRegular
, shouldResistFingerprinting
);
143 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Create(
144 uint32_t aCookieBehavior
, const nsAString
& aPartitionKey
,
145 bool aIsFirstPartyIsolated
, bool aIsOnContentBlockingAllowList
,
146 bool aShouldResistFingerprinting
) {
147 MOZ_ASSERT(NS_IsMainThread());
149 RefPtr
<CookieJarSettings
> cookieJarSettings
=
150 new CookieJarSettings(aCookieBehavior
, aIsFirstPartyIsolated
,
151 aShouldResistFingerprinting
, eProgressive
);
152 cookieJarSettings
->mPartitionKey
= aPartitionKey
;
153 cookieJarSettings
->mIsOnContentBlockingAllowList
=
154 aIsOnContentBlockingAllowList
;
156 return cookieJarSettings
.forget();
160 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::CreateForXPCOM() {
161 MOZ_ASSERT(NS_IsMainThread());
162 return Create(eRegular
, /* shouldResistFingerprinting */ false);
165 CookieJarSettings::CookieJarSettings(uint32_t aCookieBehavior
,
166 bool aIsFirstPartyIsolated
,
167 bool aShouldResistFingerprinting
,
169 : mCookieBehavior(aCookieBehavior
),
170 mIsFirstPartyIsolated(aIsFirstPartyIsolated
),
171 mIsOnContentBlockingAllowList(false),
172 mIsOnContentBlockingAllowListUpdated(false),
175 mShouldResistFingerprinting(aShouldResistFingerprinting
) {
176 MOZ_ASSERT(NS_IsMainThread());
178 mIsFirstPartyIsolated
,
180 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
183 CookieJarSettings::~CookieJarSettings() {
184 if (!NS_IsMainThread() && !mCookiePermissions
.IsEmpty()) {
186 new ReleaseCookiePermissions(std::move(mCookiePermissions
));
187 MOZ_ASSERT(mCookiePermissions
.IsEmpty());
189 SchedulerGroup::Dispatch(TaskCategory::Other
, r
.forget());
194 CookieJarSettings::InitWithURI(nsIURI
* aURI
, bool aIsPrivate
) {
197 mCookieBehavior
= nsICookieManager::GetCookieBehavior(aIsPrivate
);
199 SetPartitionKey(aURI
);
204 CookieJarSettings::GetCookieBehavior(uint32_t* aCookieBehavior
) {
205 *aCookieBehavior
= mCookieBehavior
;
210 CookieJarSettings::GetIsFirstPartyIsolated(bool* aIsFirstPartyIsolated
) {
211 *aIsFirstPartyIsolated
= mIsFirstPartyIsolated
;
216 CookieJarSettings::GetShouldResistFingerprinting(
217 bool* aShouldResistFingerprinting
) {
218 *aShouldResistFingerprinting
= mShouldResistFingerprinting
;
223 CookieJarSettings::GetRejectThirdPartyContexts(
224 bool* aRejectThirdPartyContexts
) {
225 *aRejectThirdPartyContexts
=
226 CookieJarSettings::IsRejectThirdPartyContexts(mCookieBehavior
);
231 CookieJarSettings::GetLimitForeignContexts(bool* aLimitForeignContexts
) {
232 *aLimitForeignContexts
=
233 mCookieBehavior
== nsICookieService::BEHAVIOR_LIMIT_FOREIGN
||
234 (StaticPrefs::privacy_dynamic_firstparty_limitForeign() &&
236 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
241 CookieJarSettings::GetBlockingAllThirdPartyContexts(
242 bool* aBlockingAllThirdPartyContexts
) {
243 // XXX For non-cookie forms of storage, we handle BEHAVIOR_LIMIT_FOREIGN by
244 // simply rejecting the request to use the storage. In the future, if we
245 // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense
246 // for non-cookie storage types, this may change.
247 *aBlockingAllThirdPartyContexts
=
248 mCookieBehavior
== nsICookieService::BEHAVIOR_LIMIT_FOREIGN
||
249 (!StaticPrefs::network_cookie_rejectForeignWithExceptions_enabled() &&
250 mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_FOREIGN
);
255 CookieJarSettings::GetBlockingAllContexts(bool* aBlockingAllContexts
) {
256 *aBlockingAllContexts
= mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT
;
261 CookieJarSettings::GetPartitionForeign(bool* aPartitionForeign
) {
264 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
269 CookieJarSettings::SetPartitionForeign(bool aPartitionForeign
) {
270 if (mIsFirstPartyIsolated
) {
274 if (aPartitionForeign
) {
276 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
282 CookieJarSettings::GetIsOnContentBlockingAllowList(
283 bool* aIsOnContentBlockingAllowList
) {
284 *aIsOnContentBlockingAllowList
= mIsOnContentBlockingAllowList
;
289 CookieJarSettings::GetPartitionKey(nsAString
& aPartitionKey
) {
290 aPartitionKey
= mPartitionKey
;
295 CookieJarSettings::GetFingerprintingRandomizationKey(
296 nsTArray
<uint8_t>& aFingerprintingRandomizationKey
) {
297 if (!mFingerprintingRandomKey
) {
298 return NS_ERROR_NOT_AVAILABLE
;
301 aFingerprintingRandomizationKey
= mFingerprintingRandomKey
->Clone();
306 CookieJarSettings::CookiePermission(nsIPrincipal
* aPrincipal
,
307 uint32_t* aCookiePermission
) {
308 MOZ_ASSERT(NS_IsMainThread());
309 NS_ENSURE_ARG_POINTER(aPrincipal
);
310 NS_ENSURE_ARG_POINTER(aCookiePermission
);
312 *aCookiePermission
= nsIPermissionManager::UNKNOWN_ACTION
;
316 // Let's see if we know this permission.
317 if (!mCookiePermissions
.IsEmpty()) {
318 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
320 rv
= permission
->Matches(aPrincipal
, false, &match
);
321 if (NS_WARN_IF(NS_FAILED(rv
)) || !match
) {
325 rv
= permission
->GetCapability(aCookiePermission
);
326 if (NS_WARN_IF(NS_FAILED(rv
))) {
334 // Let's ask the permission manager.
335 PermissionManager
* pm
= PermissionManager::GetInstance();
336 if (NS_WARN_IF(!pm
)) {
337 return NS_ERROR_FAILURE
;
340 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
341 // Check if this protocol doesn't allow cookies.
343 nsCOMPtr
<nsIURI
> uri
;
344 BasePrincipal::Cast(aPrincipal
)->GetURI(getter_AddRefs(uri
));
346 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_FORBIDS_COOKIE_ACCESS
,
348 if (NS_FAILED(rv
) || hasFlags
) {
349 *aCookiePermission
= PermissionManager::DENY_ACTION
;
350 rv
= NS_OK
; // Reset, so it's not caught as a bad status after the `else`.
351 } else // Note the tricky `else` which controls the call below.
354 rv
= pm
->TestPermissionFromPrincipal(aPrincipal
, "cookie"_ns
,
356 if (NS_WARN_IF(NS_FAILED(rv
))) {
360 // Let's store the permission, also if the result is UNKNOWN in order to avoid
363 nsCOMPtr
<nsIPermission
> permission
=
364 Permission::Create(aPrincipal
, "cookie"_ns
, *aCookiePermission
, 0, 0, 0);
366 mCookiePermissions
.AppendElement(permission
);
373 void CookieJarSettings::Serialize(CookieJarSettingsArgs
& aData
) {
374 MOZ_ASSERT(NS_IsMainThread());
376 aData
.isFixed() = mState
== eFixed
;
377 aData
.cookieBehavior() = mCookieBehavior
;
378 aData
.isFirstPartyIsolated() = mIsFirstPartyIsolated
;
379 aData
.shouldResistFingerprinting() = mShouldResistFingerprinting
;
380 aData
.isOnContentBlockingAllowList() = mIsOnContentBlockingAllowList
;
381 aData
.partitionKey() = mPartitionKey
;
382 if (mFingerprintingRandomKey
) {
383 aData
.hasFingerprintingRandomizationKey() = true;
384 aData
.fingerprintingRandomizationKey() = mFingerprintingRandomKey
->Clone();
386 aData
.hasFingerprintingRandomizationKey() = false;
389 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
390 nsCOMPtr
<nsIPrincipal
> principal
;
391 nsresult rv
= permission
->GetPrincipal(getter_AddRefs(principal
));
392 if (NS_WARN_IF(NS_FAILED(rv
))) {
396 ipc::PrincipalInfo principalInfo
;
397 rv
= PrincipalToPrincipalInfo(principal
, &principalInfo
,
398 true /* aSkipBaseDomain */);
399 if (NS_WARN_IF(NS_FAILED(rv
))) {
403 uint32_t cookiePermission
= 0;
404 rv
= permission
->GetCapability(&cookiePermission
);
405 if (NS_WARN_IF(NS_FAILED(rv
))) {
409 aData
.cookiePermissions().AppendElement(
410 CookiePermissionData(principalInfo
, cookiePermission
));
416 /* static */ void CookieJarSettings::Deserialize(
417 const CookieJarSettingsArgs
& aData
,
418 nsICookieJarSettings
** aCookieJarSettings
) {
419 MOZ_ASSERT(NS_IsMainThread());
421 CookiePermissionList list
;
422 for (const CookiePermissionData
& data
: aData
.cookiePermissions()) {
423 auto principalOrErr
= PrincipalInfoToPrincipal(data
.principalInfo());
424 if (NS_WARN_IF(principalOrErr
.isErr())) {
428 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
430 nsCOMPtr
<nsIPermission
> permission
= Permission::Create(
431 principal
, "cookie"_ns
, data
.cookiePermission(), 0, 0, 0);
432 if (NS_WARN_IF(!permission
)) {
436 list
.AppendElement(permission
);
439 RefPtr
<CookieJarSettings
> cookieJarSettings
= new CookieJarSettings(
440 aData
.cookieBehavior(), aData
.isFirstPartyIsolated(),
441 aData
.shouldResistFingerprinting(),
442 aData
.isFixed() ? eFixed
: eProgressive
);
444 cookieJarSettings
->mIsOnContentBlockingAllowList
=
445 aData
.isOnContentBlockingAllowList();
446 cookieJarSettings
->mCookiePermissions
= std::move(list
);
447 cookieJarSettings
->mPartitionKey
= aData
.partitionKey();
448 cookieJarSettings
->mShouldResistFingerprinting
=
449 aData
.shouldResistFingerprinting();
451 if (aData
.hasFingerprintingRandomizationKey()) {
452 cookieJarSettings
->mFingerprintingRandomKey
.emplace(
453 aData
.fingerprintingRandomizationKey().Clone());
456 cookieJarSettings
.forget(aCookieJarSettings
);
459 void CookieJarSettings::Merge(const CookieJarSettingsArgs
& aData
) {
460 MOZ_ASSERT(NS_IsMainThread());
462 mCookieBehavior
== aData
.cookieBehavior() ||
463 (mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
464 aData
.cookieBehavior() ==
465 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) ||
467 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
468 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
));
470 if (mState
== eFixed
) {
474 // Merge cookie behavior pref values
475 if (mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
476 aData
.cookieBehavior() ==
477 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) {
478 // If the other side has decided to partition third-party cookies, update
479 // our side when first-party isolation is disabled.
480 if (!mIsFirstPartyIsolated
) {
482 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
485 if (mCookieBehavior
==
486 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
487 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
) {
488 // If we've decided to partition third-party cookies, the other side may not
489 // have caught up yet unless it has first-party isolation enabled.
490 if (aData
.isFirstPartyIsolated()) {
491 mCookieBehavior
= nsICookieService::BEHAVIOR_REJECT_TRACKER
;
492 mIsFirstPartyIsolated
= true;
495 // Ignore all other cases.
497 mIsFirstPartyIsolated
,
499 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
501 if (aData
.shouldResistFingerprinting()) {
502 mShouldResistFingerprinting
= true;
505 PermissionComparator comparator
;
507 for (const CookiePermissionData
& data
: aData
.cookiePermissions()) {
508 auto principalOrErr
= PrincipalInfoToPrincipal(data
.principalInfo());
509 if (NS_WARN_IF(principalOrErr
.isErr())) {
513 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
514 nsCOMPtr
<nsIPermission
> permission
= Permission::Create(
515 principal
, "cookie"_ns
, data
.cookiePermission(), 0, 0, 0);
516 if (NS_WARN_IF(!permission
)) {
520 if (!mCookiePermissions
.Contains(permission
, comparator
)) {
521 mCookiePermissions
.AppendElement(permission
);
526 void CookieJarSettings::SetPartitionKey(nsIURI
* aURI
) {
529 OriginAttributes attrs
;
530 attrs
.SetPartitionKey(aURI
);
531 mPartitionKey
= std::move(attrs
.mPartitionKey
);
534 void CookieJarSettings::UpdateIsOnContentBlockingAllowList(
535 nsIChannel
* aChannel
) {
536 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
537 MOZ_ASSERT(aChannel
);
539 // Early return if the flag was updated before.
540 if (mIsOnContentBlockingAllowListUpdated
) {
543 mIsOnContentBlockingAllowListUpdated
= true;
545 nsCOMPtr
<nsILoadInfo
> loadInfo
= aChannel
->LoadInfo();
547 nsCOMPtr
<nsIURI
> uri
;
548 nsresult rv
= aChannel
->GetURI(getter_AddRefs(uri
));
549 if (NS_WARN_IF(NS_FAILED(rv
))) {
553 // We need to recompute the ContentBlockingAllowListPrincipal here for the
554 // top level channel because we might navigate from the the initial
555 // about:blank page or the existing page which may have a different origin
556 // than the URI we are going to load here. Thus, we need to recompute the
557 // prinicpal in order to get the correct ContentBlockingAllowListPrincipal.
558 nsCOMPtr
<nsIPrincipal
> contentBlockingAllowListPrincipal
;
559 OriginAttributes attrs
;
560 loadInfo
->GetOriginAttributes(&attrs
);
561 ContentBlockingAllowList::RecomputePrincipal(
562 uri
, attrs
, getter_AddRefs(contentBlockingAllowListPrincipal
));
564 if (!contentBlockingAllowListPrincipal
||
565 !contentBlockingAllowListPrincipal
->GetIsContentPrincipal()) {
569 Unused
<< ContentBlockingAllowList::Check(contentBlockingAllowListPrincipal
,
570 NS_UsePrivateBrowsing(aChannel
),
571 mIsOnContentBlockingAllowList
);
575 bool CookieJarSettings::IsRejectThirdPartyContexts(uint32_t aCookieBehavior
) {
576 return aCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
||
578 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
||
579 IsRejectThirdPartyWithExceptions(aCookieBehavior
);
583 bool CookieJarSettings::IsRejectThirdPartyWithExceptions(
584 uint32_t aCookieBehavior
) {
585 return aCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_FOREIGN
&&
586 StaticPrefs::network_cookie_rejectForeignWithExceptions_enabled();
590 CookieJarSettings::Read(nsIObjectInputStream
* aStream
) {
591 nsresult rv
= aStream
->Read32(&mCookieBehavior
);
592 if (NS_WARN_IF(NS_FAILED(rv
))) {
596 rv
= aStream
->ReadBoolean(&mIsFirstPartyIsolated
);
597 if (NS_WARN_IF(NS_FAILED(rv
))) {
601 rv
= aStream
->ReadBoolean(&mShouldResistFingerprinting
);
602 if (NS_WARN_IF(NS_FAILED(rv
))) {
607 aStream
->ReadBoolean(&isFixed
);
608 if (NS_WARN_IF(NS_FAILED(rv
))) {
611 mState
= isFixed
? eFixed
: eProgressive
;
613 rv
= aStream
->ReadBoolean(&mIsOnContentBlockingAllowList
);
614 if (NS_WARN_IF(NS_FAILED(rv
))) {
618 rv
= aStream
->ReadString(mPartitionKey
);
619 if (NS_WARN_IF(NS_FAILED(rv
))) {
623 // Deserializing the cookie permission list.
624 uint32_t cookiePermissionsLength
;
625 rv
= aStream
->Read32(&cookiePermissionsLength
);
626 if (NS_WARN_IF(NS_FAILED(rv
))) {
630 if (!cookiePermissionsLength
) {
631 // Bailing out early because there is no cookie permission.
635 CookiePermissionList list
;
636 mCookiePermissions
.SetCapacity(cookiePermissionsLength
);
637 for (uint32_t i
= 0; i
< cookiePermissionsLength
; ++i
) {
638 nsAutoCString principalJSON
;
639 aStream
->ReadCString(principalJSON
);
640 if (NS_WARN_IF(NS_FAILED(rv
))) {
644 nsCOMPtr
<nsIPrincipal
> principal
= BasePrincipal::FromJSON(principalJSON
);
646 if (NS_WARN_IF(!principal
)) {
650 uint32_t cookiePermission
;
651 aStream
->Read32(&cookiePermission
);
652 if (NS_WARN_IF(NS_FAILED(rv
))) {
656 nsCOMPtr
<nsIPermission
> permission
=
657 Permission::Create(principal
, "cookie"_ns
, cookiePermission
, 0, 0, 0);
658 if (NS_WARN_IF(!permission
)) {
662 list
.AppendElement(permission
);
665 mCookiePermissions
= std::move(list
);
671 CookieJarSettings::Write(nsIObjectOutputStream
* aStream
) {
672 nsresult rv
= aStream
->Write32(mCookieBehavior
);
673 if (NS_WARN_IF(NS_FAILED(rv
))) {
677 rv
= aStream
->WriteBoolean(mIsFirstPartyIsolated
);
678 if (NS_WARN_IF(NS_FAILED(rv
))) {
682 rv
= aStream
->WriteBoolean(mShouldResistFingerprinting
);
683 if (NS_WARN_IF(NS_FAILED(rv
))) {
687 rv
= aStream
->WriteBoolean(mState
== eFixed
);
688 if (NS_WARN_IF(NS_FAILED(rv
))) {
692 rv
= aStream
->WriteBoolean(mIsOnContentBlockingAllowList
);
693 if (NS_WARN_IF(NS_FAILED(rv
))) {
697 rv
= aStream
->WriteWStringZ(mPartitionKey
.get());
698 if (NS_WARN_IF(NS_FAILED(rv
))) {
702 // Serializing the cookie permission list. It will first write the length of
703 // the list, and then, write the cookie permission consecutively.
704 uint32_t cookiePermissionsLength
= mCookiePermissions
.Length();
705 rv
= aStream
->Write32(cookiePermissionsLength
);
706 if (NS_WARN_IF(NS_FAILED(rv
))) {
710 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
711 nsCOMPtr
<nsIPrincipal
> principal
;
712 nsresult rv
= permission
->GetPrincipal(getter_AddRefs(principal
));
713 if (NS_WARN_IF(NS_FAILED(rv
))) {
717 nsAutoCString principalJSON
;
718 BasePrincipal::Cast(principal
)->ToJSON(principalJSON
);
720 rv
= aStream
->WriteStringZ(principalJSON
.get());
721 if (NS_WARN_IF(NS_FAILED(rv
))) {
725 uint32_t cookiePermission
= 0;
726 rv
= permission
->GetCapability(&cookiePermission
);
727 if (NS_WARN_IF(NS_FAILED(rv
))) {
731 rv
= aStream
->Write32(cookiePermission
);
732 if (NS_WARN_IF(NS_FAILED(rv
))) {
741 } // namespace mozilla