Bug 1887774 convert from MediaEnginePrefs to AudioProcessing config in AudioInputProc...
[gecko.git] / netwerk / cookie / CookieJarSettings.cpp
blob9e598c296f2f0e2b0d870399425f16fc331dff07
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"
25 #endif
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"
34 namespace mozilla {
35 namespace net {
37 NS_IMPL_CLASSINFO(CookieJarSettings, nullptr, nsIClassInfo::THREADSAFE,
38 COOKIEJARSETTINGS_CID)
40 NS_IMPL_ISUPPORTS_CI(CookieJarSettings, nsICookieJarSettings, nsISerializable)
42 static StaticRefPtr<CookieJarSettings> sBlockinAll;
44 namespace {
46 class PermissionComparator {
47 public:
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))) {
52 return false;
55 nsCOMPtr<nsIPrincipal> principalB;
56 rv = aB->GetPrincipal(getter_AddRefs(principalB));
57 if (NS_WARN_IF(NS_FAILED(rv))) {
58 return false;
61 bool equals = false;
62 rv = principalA->Equals(principalB, &equals);
63 if (NS_WARN_IF(NS_FAILED(rv))) {
64 return false;
67 return equals;
71 class ReleaseCookiePermissions final : public Runnable {
72 public:
73 explicit ReleaseCookiePermissions(nsTArray<RefPtr<nsIPermission>>&& aArray)
74 : Runnable("ReleaseCookiePermissions"), mArray(std::move(aArray)) {}
76 NS_IMETHOD Run() override {
77 MOZ_ASSERT(NS_IsMainThread());
78 mArray.Clear();
79 return NS_OK;
82 private:
83 nsTArray<RefPtr<nsIPermission>> mArray;
86 } // namespace
88 // static
89 already_AddRefed<nsICookieJarSettings> CookieJarSettings::GetBlockingAll(
90 bool aShouldResistFingerprinting) {
91 MOZ_ASSERT(NS_IsMainThread());
93 if (sBlockinAll) {
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);
105 // static
106 already_AddRefed<nsICookieJarSettings> CookieJarSettings::Create(
107 CreateMode aMode, bool aShouldResistFingerprinting) {
108 MOZ_ASSERT(NS_IsMainThread());
110 RefPtr<CookieJarSettings> cookieJarSettings;
112 switch (aMode) {
113 case eRegular:
114 case ePrivate:
115 cookieJarSettings = new CookieJarSettings(
116 nsICookieManager::GetCookieBehavior(aMode == ePrivate),
117 OriginAttributes::IsFirstPartyEnabled(), aShouldResistFingerprinting,
118 eProgressive);
119 break;
121 default:
122 MOZ_CRASH("Unexpected create mode.");
125 return cookieJarSettings.forget();
128 // static
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);
145 // static
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();
162 // static
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,
171 State aState)
172 : mCookieBehavior(aCookieBehavior),
173 mIsFirstPartyIsolated(aIsFirstPartyIsolated),
174 mIsOnContentBlockingAllowList(false),
175 mIsOnContentBlockingAllowListUpdated(false),
176 mState(aState),
177 mToBeMerged(false),
178 mShouldResistFingerprinting(aShouldResistFingerprinting),
179 mTopLevelWindowContextId(0) {
180 MOZ_ASSERT(NS_IsMainThread());
181 MOZ_ASSERT_IF(
182 mIsFirstPartyIsolated,
183 mCookieBehavior !=
184 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
187 CookieJarSettings::~CookieJarSettings() {
188 if (!NS_IsMainThread() && !mCookiePermissions.IsEmpty()) {
189 RefPtr<Runnable> r =
190 new ReleaseCookiePermissions(std::move(mCookiePermissions));
191 MOZ_ASSERT(mCookiePermissions.IsEmpty());
192 SchedulerGroup::Dispatch(r.forget());
196 NS_IMETHODIMP
197 CookieJarSettings::InitWithURI(nsIURI* aURI, bool aIsPrivate) {
198 NS_ENSURE_ARG(aURI);
200 mCookieBehavior = nsICookieManager::GetCookieBehavior(aIsPrivate);
202 SetPartitionKey(aURI, false);
203 return NS_OK;
206 NS_IMETHODIMP
207 CookieJarSettings::GetCookieBehavior(uint32_t* aCookieBehavior) {
208 *aCookieBehavior = mCookieBehavior;
209 return NS_OK;
212 NS_IMETHODIMP
213 CookieJarSettings::GetIsFirstPartyIsolated(bool* aIsFirstPartyIsolated) {
214 *aIsFirstPartyIsolated = mIsFirstPartyIsolated;
215 return NS_OK;
218 NS_IMETHODIMP
219 CookieJarSettings::GetShouldResistFingerprinting(
220 bool* aShouldResistFingerprinting) {
221 *aShouldResistFingerprinting = mShouldResistFingerprinting;
222 return NS_OK;
225 NS_IMETHODIMP
226 CookieJarSettings::GetRejectThirdPartyContexts(
227 bool* aRejectThirdPartyContexts) {
228 *aRejectThirdPartyContexts =
229 CookieJarSettings::IsRejectThirdPartyContexts(mCookieBehavior);
230 return NS_OK;
233 NS_IMETHODIMP
234 CookieJarSettings::GetLimitForeignContexts(bool* aLimitForeignContexts) {
235 *aLimitForeignContexts =
236 mCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN ||
237 (StaticPrefs::privacy_dynamic_firstparty_limitForeign() &&
238 mCookieBehavior ==
239 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN);
240 return NS_OK;
243 NS_IMETHODIMP
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;
253 return NS_OK;
256 NS_IMETHODIMP
257 CookieJarSettings::GetBlockingAllContexts(bool* aBlockingAllContexts) {
258 *aBlockingAllContexts = mCookieBehavior == nsICookieService::BEHAVIOR_REJECT;
259 return NS_OK;
262 NS_IMETHODIMP
263 CookieJarSettings::GetPartitionForeign(bool* aPartitionForeign) {
264 *aPartitionForeign =
265 mCookieBehavior ==
266 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
267 return NS_OK;
270 NS_IMETHODIMP
271 CookieJarSettings::SetPartitionForeign(bool aPartitionForeign) {
272 if (mIsFirstPartyIsolated) {
273 return NS_OK;
276 if (aPartitionForeign) {
277 mCookieBehavior =
278 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
280 return NS_OK;
283 NS_IMETHODIMP
284 CookieJarSettings::GetIsOnContentBlockingAllowList(
285 bool* aIsOnContentBlockingAllowList) {
286 *aIsOnContentBlockingAllowList = mIsOnContentBlockingAllowList;
287 return NS_OK;
290 NS_IMETHODIMP
291 CookieJarSettings::GetPartitionKey(nsAString& aPartitionKey) {
292 aPartitionKey = mPartitionKey;
293 return NS_OK;
296 NS_IMETHODIMP
297 CookieJarSettings::GetFingerprintingRandomizationKey(
298 nsTArray<uint8_t>& aFingerprintingRandomizationKey) {
299 if (!mFingerprintingRandomKey) {
300 return NS_ERROR_NOT_AVAILABLE;
303 aFingerprintingRandomizationKey = mFingerprintingRandomKey->Clone();
304 return NS_OK;
307 NS_IMETHODIMP
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;
316 nsresult rv;
318 // Let's see if we know this permission.
319 if (!mCookiePermissions.IsEmpty()) {
320 for (const RefPtr<nsIPermission>& permission : mCookiePermissions) {
321 bool match = false;
322 rv = permission->Matches(aPrincipal, false, &match);
323 if (NS_WARN_IF(NS_FAILED(rv)) || !match) {
324 continue;
327 rv = permission->GetCapability(aCookiePermission);
328 if (NS_WARN_IF(NS_FAILED(rv))) {
329 return rv;
332 return NS_OK;
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.
344 bool hasFlags;
345 nsCOMPtr<nsIURI> uri;
346 BasePrincipal::Cast(aPrincipal)->GetURI(getter_AddRefs(uri));
348 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_FORBIDS_COOKIE_ACCESS,
349 &hasFlags);
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.
354 #endif
356 rv = pm->TestPermissionFromPrincipal(aPrincipal, "cookie"_ns,
357 aCookiePermission);
358 if (NS_WARN_IF(NS_FAILED(rv))) {
359 return rv;
362 // Let's store the permission, also if the result is UNKNOWN in order to avoid
363 // race conditions.
365 nsCOMPtr<nsIPermission> permission =
366 Permission::Create(aPrincipal, "cookie"_ns, *aCookiePermission, 0, 0, 0);
367 if (permission) {
368 mCookiePermissions.AppendElement(permission);
371 mToBeMerged = true;
372 return NS_OK;
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();
387 } else {
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))) {
395 continue;
398 ipc::PrincipalInfo principalInfo;
399 rv = PrincipalToPrincipalInfo(principal, &principalInfo,
400 true /* aSkipBaseDomain */);
401 if (NS_WARN_IF(NS_FAILED(rv))) {
402 continue;
405 uint32_t cookiePermission = 0;
406 rv = permission->GetCapability(&cookiePermission);
407 if (NS_WARN_IF(NS_FAILED(rv))) {
408 continue;
411 aData.cookiePermissions().AppendElement(
412 CookiePermissionData(principalInfo, cookiePermission));
415 aData.topLevelWindowContextId() = mTopLevelWindowContextId;
417 mToBeMerged = false;
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())) {
429 continue;
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)) {
437 continue;
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());
467 MOZ_ASSERT(
468 mCookieBehavior == aData.cookieBehavior() ||
469 (mCookieBehavior == nsICookieService::BEHAVIOR_REJECT_TRACKER &&
470 aData.cookieBehavior() ==
471 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN) ||
472 (mCookieBehavior ==
473 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN &&
474 aData.cookieBehavior() == nsICookieService::BEHAVIOR_REJECT_TRACKER));
476 if (mState == eFixed) {
477 return;
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) {
487 mCookieBehavior =
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.
502 MOZ_ASSERT_IF(
503 mIsFirstPartyIsolated,
504 mCookieBehavior !=
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())) {
516 continue;
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)) {
523 continue;
526 if (!mCookiePermissions.Contains(permission, comparator)) {
527 mCookiePermissions.AppendElement(permission);
532 void CookieJarSettings::SetPartitionKey(nsIURI* aURI,
533 bool aForeignByAncestorContext) {
534 MOZ_ASSERT(aURI);
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) {
558 return;
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))) {
567 return;
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()) {
583 return;
586 Unused << ContentBlockingAllowList::Check(contentBlockingAllowListPrincipal,
587 NS_UsePrivateBrowsing(aChannel),
588 mIsOnContentBlockingAllowList);
591 // static
592 bool CookieJarSettings::IsRejectThirdPartyContexts(uint32_t aCookieBehavior) {
593 return aCookieBehavior == nsICookieService::BEHAVIOR_REJECT_TRACKER ||
594 aCookieBehavior ==
595 nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
598 NS_IMETHODIMP
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))) {
603 return rv;
606 rv = aStream->ReadBoolean(&mIsFirstPartyIsolated);
607 if (NS_WARN_IF(NS_FAILED(rv))) {
608 return rv;
611 rv = aStream->ReadBoolean(&mShouldResistFingerprinting);
612 if (NS_WARN_IF(NS_FAILED(rv))) {
613 return rv;
616 bool isFixed;
617 aStream->ReadBoolean(&isFixed);
618 if (NS_WARN_IF(NS_FAILED(rv))) {
619 return rv;
621 mState = isFixed ? eFixed : eProgressive;
623 rv = aStream->ReadBoolean(&mIsOnContentBlockingAllowList);
624 if (NS_WARN_IF(NS_FAILED(rv))) {
625 return rv;
628 rv = aStream->ReadString(mPartitionKey);
629 if (NS_WARN_IF(NS_FAILED(rv))) {
630 return rv;
633 // Deserializing the cookie permission list.
634 uint32_t cookiePermissionsLength;
635 rv = aStream->Read32(&cookiePermissionsLength);
636 if (NS_WARN_IF(NS_FAILED(rv))) {
637 return rv;
640 if (!cookiePermissionsLength) {
641 // Bailing out early because there is no cookie permission.
642 return NS_OK;
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))) {
651 return rv;
654 nsCOMPtr<nsIPrincipal> principal = BasePrincipal::FromJSON(principalJSON);
656 if (NS_WARN_IF(!principal)) {
657 continue;
660 uint32_t cookiePermission;
661 aStream->Read32(&cookiePermission);
662 if (NS_WARN_IF(NS_FAILED(rv))) {
663 return rv;
666 nsCOMPtr<nsIPermission> permission =
667 Permission::Create(principal, "cookie"_ns, cookiePermission, 0, 0, 0);
668 if (NS_WARN_IF(!permission)) {
669 continue;
672 list.AppendElement(permission);
675 mCookiePermissions = std::move(list);
677 return NS_OK;
680 NS_IMETHODIMP
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))) {
685 return rv;
688 rv = aStream->WriteBoolean(mIsFirstPartyIsolated);
689 if (NS_WARN_IF(NS_FAILED(rv))) {
690 return rv;
693 rv = aStream->WriteBoolean(mShouldResistFingerprinting);
694 if (NS_WARN_IF(NS_FAILED(rv))) {
695 return rv;
698 rv = aStream->WriteBoolean(mState == eFixed);
699 if (NS_WARN_IF(NS_FAILED(rv))) {
700 return rv;
703 rv = aStream->WriteBoolean(mIsOnContentBlockingAllowList);
704 if (NS_WARN_IF(NS_FAILED(rv))) {
705 return rv;
708 rv = aStream->WriteWStringZ(mPartitionKey.get());
709 if (NS_WARN_IF(NS_FAILED(rv))) {
710 return 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))) {
718 return 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))) {
725 continue;
728 nsAutoCString principalJSON;
729 BasePrincipal::Cast(principal)->ToJSON(principalJSON);
731 rv = aStream->WriteStringZ(principalJSON.get());
732 if (NS_WARN_IF(NS_FAILED(rv))) {
733 return rv;
736 uint32_t cookiePermission = 0;
737 rv = permission->GetCapability(&cookiePermission);
738 if (NS_WARN_IF(NS_FAILED(rv))) {
739 continue;
742 rv = aStream->Write32(cookiePermission);
743 if (NS_WARN_IF(NS_FAILED(rv))) {
744 return rv;
748 return NS_OK;
751 } // namespace net
752 } // namespace mozilla