PartitionedLocalStorage.cpp (3939B)
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/. */ 6 7 #include "PartitionedLocalStorage.h" 8 9 #include "SessionStorageCache.h" 10 #include "mozilla/dom/StorageBinding.h" 11 #include "nsContentUtils.h" 12 13 namespace mozilla::dom { 14 15 NS_IMPL_CYCLE_COLLECTION_INHERITED(PartitionedLocalStorage, Storage); 16 17 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PartitionedLocalStorage) 18 NS_INTERFACE_MAP_END_INHERITING(Storage) 19 20 NS_IMPL_ADDREF_INHERITED(PartitionedLocalStorage, Storage) 21 NS_IMPL_RELEASE_INHERITED(PartitionedLocalStorage, Storage) 22 23 PartitionedLocalStorage::PartitionedLocalStorage( 24 nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal, 25 nsIPrincipal* aStoragePrincipal, SessionStorageCache* aCache) 26 : Storage(aWindow, aPrincipal, aStoragePrincipal), mCache(aCache) {} 27 28 PartitionedLocalStorage::~PartitionedLocalStorage() = default; 29 30 int64_t PartitionedLocalStorage::GetOriginQuotaUsage() const { 31 return mCache->GetOriginQuotaUsage(); 32 } 33 34 uint32_t PartitionedLocalStorage::GetLength(nsIPrincipal& aSubjectPrincipal, 35 ErrorResult& aRv) { 36 if (!CanUseStorage(aSubjectPrincipal)) { 37 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 38 return 0; 39 } 40 41 return mCache->Length(); 42 } 43 44 void PartitionedLocalStorage::Key(uint32_t aIndex, nsAString& aResult, 45 nsIPrincipal& aSubjectPrincipal, 46 ErrorResult& aRv) { 47 if (!CanUseStorage(aSubjectPrincipal)) { 48 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 49 return; 50 } 51 52 mCache->Key(aIndex, aResult); 53 } 54 55 void PartitionedLocalStorage::GetItem(const nsAString& aKey, nsAString& aResult, 56 nsIPrincipal& aSubjectPrincipal, 57 ErrorResult& aRv) { 58 if (!CanUseStorage(aSubjectPrincipal)) { 59 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 60 return; 61 } 62 63 mCache->GetItem(aKey, aResult); 64 } 65 66 void PartitionedLocalStorage::GetSupportedNames(nsTArray<nsString>& aKeys) { 67 if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) { 68 // return just an empty array 69 aKeys.Clear(); 70 return; 71 } 72 73 mCache->GetKeys(aKeys); 74 } 75 76 void PartitionedLocalStorage::SetItem(const nsAString& aKey, 77 const nsAString& aValue, 78 nsIPrincipal& aSubjectPrincipal, 79 ErrorResult& aRv) { 80 if (!CanUseStorage(aSubjectPrincipal)) { 81 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 82 return; 83 } 84 85 nsString oldValue; 86 nsresult rv = mCache->SetItem(aKey, aValue, oldValue); 87 if (NS_WARN_IF(NS_FAILED(rv))) { 88 aRv.Throw(rv); 89 return; 90 } 91 92 if (rv == NS_SUCCESS_DOM_NO_OPERATION) { 93 return; 94 } 95 } 96 97 void PartitionedLocalStorage::RemoveItem(const nsAString& aKey, 98 nsIPrincipal& aSubjectPrincipal, 99 ErrorResult& aRv) { 100 if (!CanUseStorage(aSubjectPrincipal)) { 101 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 102 return; 103 } 104 105 nsString oldValue; 106 nsresult rv = mCache->RemoveItem(aKey, oldValue); 107 MOZ_ASSERT(NS_SUCCEEDED(rv)); 108 109 if (rv == NS_SUCCESS_DOM_NO_OPERATION) { 110 return; 111 } 112 } 113 114 void PartitionedLocalStorage::Clear(nsIPrincipal& aSubjectPrincipal, 115 ErrorResult& aRv) { 116 uint32_t length = GetLength(aSubjectPrincipal, aRv); 117 if (!length) { 118 return; 119 } 120 121 mCache->Clear(); 122 } 123 124 bool PartitionedLocalStorage::IsForkOf(const Storage* aOther) const { 125 MOZ_ASSERT(aOther); 126 if (aOther->Type() != eLocalStorage) { 127 return false; 128 } 129 130 return mCache == static_cast<const PartitionedLocalStorage*>(aOther)->mCache; 131 } 132 133 } // namespace mozilla::dom