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().IsPrivateBrowsing()) {
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 RefPtr
<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 mozilla::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 already_AddRefed
<nsICookieJarSettings
> CookieJarSettings::Merge(
466 const CookieJarSettingsArgs
& aData
) {
467 MOZ_RELEASE_ASSERT(NS_IsMainThread());
469 mCookieBehavior
== aData
.cookieBehavior() ||
470 (mCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
471 aData
.cookieBehavior() ==
472 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) ||
474 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
475 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
));
477 if (mState
== eFixed
) {
478 return do_AddRef(this);
481 RefPtr
<CookieJarSettings
> newCookieJarSettings
;
482 newCookieJarSettings
= Clone();
484 // Merge cookie behavior pref values
485 if (newCookieJarSettings
->mCookieBehavior
==
486 nsICookieService::BEHAVIOR_REJECT_TRACKER
&&
487 aData
.cookieBehavior() ==
488 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
) {
489 // If the other side has decided to partition third-party cookies, update
490 // our side when first-party isolation is disabled.
491 if (!newCookieJarSettings
->mIsFirstPartyIsolated
) {
492 newCookieJarSettings
->mCookieBehavior
=
493 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
496 if (newCookieJarSettings
->mCookieBehavior
==
497 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
&&
498 aData
.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER
) {
499 // If we've decided to partition third-party cookies, the other side may not
500 // have caught up yet unless it has first-party isolation enabled.
501 if (aData
.isFirstPartyIsolated()) {
502 newCookieJarSettings
->mCookieBehavior
=
503 nsICookieService::BEHAVIOR_REJECT_TRACKER
;
504 newCookieJarSettings
->mIsFirstPartyIsolated
= true;
507 // Ignore all other cases.
509 newCookieJarSettings
->mIsFirstPartyIsolated
,
510 newCookieJarSettings
->mCookieBehavior
!=
511 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
513 if (aData
.shouldResistFingerprinting()) {
514 newCookieJarSettings
->mShouldResistFingerprinting
= true;
517 // Merge partition Key. When a channel is created in the the child process and
518 // then opened in the parent process, the partition key will be created in the
519 // parent process, then sending back to the child process. Merging it here to
520 // ensure the child process has the latest value.
521 newCookieJarSettings
->mPartitionKey
= aData
.partitionKey();
523 PermissionComparator comparator
;
525 for (const CookiePermissionData
& data
: aData
.cookiePermissions()) {
526 auto principalOrErr
= PrincipalInfoToPrincipal(data
.principalInfo());
527 if (NS_WARN_IF(principalOrErr
.isErr())) {
531 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
532 nsCOMPtr
<nsIPermission
> permission
= Permission::Create(
533 principal
, "cookie"_ns
, data
.cookiePermission(), 0, 0, 0);
534 if (NS_WARN_IF(!permission
)) {
538 if (!newCookieJarSettings
->mCookiePermissions
.Contains(permission
,
540 newCookieJarSettings
->mCookiePermissions
.AppendElement(permission
);
544 return newCookieJarSettings
.forget();
547 void CookieJarSettings::SetPartitionKey(nsIURI
* aURI
,
548 bool aForeignByAncestorContext
) {
551 OriginAttributes attrs
;
552 attrs
.SetPartitionKey(aURI
, aForeignByAncestorContext
);
553 mPartitionKey
= std::move(attrs
.mPartitionKey
);
556 void CookieJarSettings::UpdatePartitionKeyForDocumentLoadedByChannel(
557 nsIChannel
* aChannel
) {
558 nsCOMPtr
<nsILoadInfo
> loadInfo
= aChannel
->LoadInfo();
559 bool thirdParty
= AntiTrackingUtils::IsThirdPartyChannel(aChannel
);
560 bool foreignByAncestorContext
=
561 thirdParty
&& !loadInfo
->GetIsThirdPartyContextToTopWindow();
562 StoragePrincipalHelper::UpdatePartitionKeyWithForeignAncestorBit(
563 mPartitionKey
, foreignByAncestorContext
);
566 void CookieJarSettings::UpdateIsOnContentBlockingAllowList(
567 nsIChannel
* aChannel
) {
568 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
569 MOZ_ASSERT(aChannel
);
571 // Early return if the flag was updated before.
572 if (mIsOnContentBlockingAllowListUpdated
) {
575 mIsOnContentBlockingAllowListUpdated
= true;
577 nsCOMPtr
<nsILoadInfo
> loadInfo
= aChannel
->LoadInfo();
579 nsCOMPtr
<nsIURI
> uri
;
580 nsresult rv
= aChannel
->GetURI(getter_AddRefs(uri
));
581 if (NS_WARN_IF(NS_FAILED(rv
))) {
585 // We need to recompute the ContentBlockingAllowListPrincipal here for the
586 // top level channel because we might navigate from the the initial
587 // about:blank page or the existing page which may have a different origin
588 // than the URI we are going to load here. Thus, we need to recompute the
589 // prinicpal in order to get the correct ContentBlockingAllowListPrincipal.
590 nsCOMPtr
<nsIPrincipal
> contentBlockingAllowListPrincipal
;
591 OriginAttributes attrs
;
592 loadInfo
->GetOriginAttributes(&attrs
);
593 ContentBlockingAllowList::RecomputePrincipal(
594 uri
, attrs
, getter_AddRefs(contentBlockingAllowListPrincipal
));
596 if (!contentBlockingAllowListPrincipal
||
597 !contentBlockingAllowListPrincipal
->GetIsContentPrincipal()) {
601 Unused
<< ContentBlockingAllowList::Check(contentBlockingAllowListPrincipal
,
602 NS_UsePrivateBrowsing(aChannel
),
603 mIsOnContentBlockingAllowList
);
607 bool CookieJarSettings::IsRejectThirdPartyContexts(uint32_t aCookieBehavior
) {
608 return aCookieBehavior
== nsICookieService::BEHAVIOR_REJECT_TRACKER
||
610 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
;
614 CookieJarSettings::Read(nsIObjectInputStream
* aStream
) {
615 MOZ_RELEASE_ASSERT(NS_IsMainThread());
616 nsresult rv
= aStream
->Read32(&mCookieBehavior
);
617 if (NS_WARN_IF(NS_FAILED(rv
))) {
621 rv
= aStream
->ReadBoolean(&mIsFirstPartyIsolated
);
622 if (NS_WARN_IF(NS_FAILED(rv
))) {
626 rv
= aStream
->ReadBoolean(&mShouldResistFingerprinting
);
627 if (NS_WARN_IF(NS_FAILED(rv
))) {
632 aStream
->ReadBoolean(&isFixed
);
633 if (NS_WARN_IF(NS_FAILED(rv
))) {
636 mState
= isFixed
? eFixed
: eProgressive
;
638 rv
= aStream
->ReadBoolean(&mIsOnContentBlockingAllowList
);
639 if (NS_WARN_IF(NS_FAILED(rv
))) {
643 rv
= aStream
->ReadString(mPartitionKey
);
644 if (NS_WARN_IF(NS_FAILED(rv
))) {
648 // Deserializing the cookie permission list.
649 uint32_t cookiePermissionsLength
;
650 rv
= aStream
->Read32(&cookiePermissionsLength
);
651 if (NS_WARN_IF(NS_FAILED(rv
))) {
655 if (!cookiePermissionsLength
) {
656 // Bailing out early because there is no cookie permission.
660 CookiePermissionList list
;
661 mCookiePermissions
.SetCapacity(cookiePermissionsLength
);
662 for (uint32_t i
= 0; i
< cookiePermissionsLength
; ++i
) {
663 nsAutoCString principalJSON
;
664 aStream
->ReadCString(principalJSON
);
665 if (NS_WARN_IF(NS_FAILED(rv
))) {
669 nsCOMPtr
<nsIPrincipal
> principal
= BasePrincipal::FromJSON(principalJSON
);
671 if (NS_WARN_IF(!principal
)) {
675 uint32_t cookiePermission
;
676 aStream
->Read32(&cookiePermission
);
677 if (NS_WARN_IF(NS_FAILED(rv
))) {
681 nsCOMPtr
<nsIPermission
> permission
=
682 Permission::Create(principal
, "cookie"_ns
, cookiePermission
, 0, 0, 0);
683 if (NS_WARN_IF(!permission
)) {
687 list
.AppendElement(permission
);
690 mCookiePermissions
= std::move(list
);
696 CookieJarSettings::Write(nsIObjectOutputStream
* aStream
) {
697 MOZ_RELEASE_ASSERT(NS_IsMainThread());
698 nsresult rv
= aStream
->Write32(mCookieBehavior
);
699 if (NS_WARN_IF(NS_FAILED(rv
))) {
703 rv
= aStream
->WriteBoolean(mIsFirstPartyIsolated
);
704 if (NS_WARN_IF(NS_FAILED(rv
))) {
708 rv
= aStream
->WriteBoolean(mShouldResistFingerprinting
);
709 if (NS_WARN_IF(NS_FAILED(rv
))) {
713 rv
= aStream
->WriteBoolean(mState
== eFixed
);
714 if (NS_WARN_IF(NS_FAILED(rv
))) {
718 rv
= aStream
->WriteBoolean(mIsOnContentBlockingAllowList
);
719 if (NS_WARN_IF(NS_FAILED(rv
))) {
723 rv
= aStream
->WriteWStringZ(mPartitionKey
.get());
724 if (NS_WARN_IF(NS_FAILED(rv
))) {
728 // Serializing the cookie permission list. It will first write the length of
729 // the list, and then, write the cookie permission consecutively.
730 uint32_t cookiePermissionsLength
= mCookiePermissions
.Length();
731 rv
= aStream
->Write32(cookiePermissionsLength
);
732 if (NS_WARN_IF(NS_FAILED(rv
))) {
736 for (const RefPtr
<nsIPermission
>& permission
: mCookiePermissions
) {
737 nsCOMPtr
<nsIPrincipal
> principal
;
738 nsresult rv
= permission
->GetPrincipal(getter_AddRefs(principal
));
739 if (NS_WARN_IF(NS_FAILED(rv
))) {
743 nsAutoCString principalJSON
;
744 BasePrincipal::Cast(principal
)->ToJSON(principalJSON
);
746 rv
= aStream
->WriteStringZ(principalJSON
.get());
747 if (NS_WARN_IF(NS_FAILED(rv
))) {
751 uint32_t cookiePermission
= 0;
752 rv
= permission
->GetCapability(&cookiePermission
);
753 if (NS_WARN_IF(NS_FAILED(rv
))) {
757 rv
= aStream
->Write32(cookiePermission
);
758 if (NS_WARN_IF(NS_FAILED(rv
))) {
767 } // namespace mozilla