Bug 1610775 [wpt PR 21336] - Update urllib3 to 1.25.8, a=testonly
[gecko.git] / dom / storage / LocalStorage.cpp
blob0b408fb96237fbf164b69d20f18393a65b308635
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 "LocalStorage.h"
8 #include "LocalStorageCache.h"
9 #include "LocalStorageManager.h"
10 #include "StorageUtils.h"
12 #include "nsIPrincipal.h"
14 #include "mozilla/dom/PermissionMessageUtils.h"
15 #include "mozilla/dom/StorageBinding.h"
16 #include "mozilla/dom/StorageEvent.h"
17 #include "mozilla/dom/StorageEventBinding.h"
18 #include "mozilla/ipc/BackgroundChild.h"
19 #include "mozilla/ipc/PBackgroundChild.h"
20 #include "mozilla/Preferences.h"
21 #include "mozilla/EnumSet.h"
22 #include "nsThreadUtils.h"
23 #include "nsContentUtils.h"
24 #include "nsServiceManagerUtils.h"
26 namespace mozilla {
28 using namespace ipc;
30 namespace dom {
32 NS_IMPL_CYCLE_COLLECTION_CLASS(LocalStorage)
33 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(LocalStorage, Storage)
34 NS_IMPL_CYCLE_COLLECTION_UNLINK(mManager)
35 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(LocalStorage, Storage)
37 CycleCollectionNoteChild(
38 cb, NS_ISUPPORTS_CAST(nsIDOMStorageManager*, tmp->mManager.get()),
39 "mManager");
40 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
42 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LocalStorage)
43 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
44 NS_INTERFACE_MAP_END_INHERITING(Storage)
46 NS_IMPL_ADDREF_INHERITED(LocalStorage, Storage)
47 NS_IMPL_RELEASE_INHERITED(LocalStorage, Storage)
49 LocalStorage::LocalStorage(nsPIDOMWindowInner* aWindow,
50 LocalStorageManager* aManager,
51 LocalStorageCache* aCache,
52 const nsAString& aDocumentURI,
53 nsIPrincipal* aPrincipal,
54 nsIPrincipal* aStoragePrincipal, bool aIsPrivate)
55 : Storage(aWindow, aPrincipal, aStoragePrincipal),
56 mManager(aManager),
57 mCache(aCache),
58 mDocumentURI(aDocumentURI),
59 mIsPrivate(aIsPrivate) {
60 mCache->Preload();
63 LocalStorage::~LocalStorage() {}
65 int64_t LocalStorage::GetOriginQuotaUsage() const {
66 return mCache->GetOriginQuotaUsage(this);
69 uint32_t LocalStorage::GetLength(nsIPrincipal& aSubjectPrincipal,
70 ErrorResult& aRv) {
71 if (!CanUseStorage(aSubjectPrincipal)) {
72 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
73 return 0;
76 uint32_t length;
77 aRv = mCache->GetLength(this, &length);
78 return length;
81 void LocalStorage::Key(uint32_t aIndex, nsAString& aResult,
82 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
83 if (!CanUseStorage(aSubjectPrincipal)) {
84 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
85 return;
88 aRv = mCache->GetKey(this, aIndex, aResult);
91 void LocalStorage::GetItem(const nsAString& aKey, nsAString& aResult,
92 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
93 if (!CanUseStorage(aSubjectPrincipal)) {
94 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
95 return;
98 aRv = mCache->GetItem(this, aKey, aResult);
101 void LocalStorage::SetItem(const nsAString& aKey, const nsAString& aData,
102 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
103 if (!CanUseStorage(aSubjectPrincipal)) {
104 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
105 return;
108 nsString data;
109 bool ok = data.Assign(aData, fallible);
110 if (!ok) {
111 aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
112 return;
115 nsString old;
116 aRv = mCache->SetItem(this, aKey, data, old);
117 if (aRv.Failed()) {
118 return;
121 if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) {
122 OnChange(aKey, old, aData);
126 void LocalStorage::RemoveItem(const nsAString& aKey,
127 nsIPrincipal& aSubjectPrincipal,
128 ErrorResult& aRv) {
129 if (!CanUseStorage(aSubjectPrincipal)) {
130 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
131 return;
134 nsAutoString old;
135 aRv = mCache->RemoveItem(this, aKey, old);
136 if (aRv.Failed()) {
137 return;
140 if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) {
141 OnChange(aKey, old, VoidString());
145 void LocalStorage::Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
146 if (!CanUseStorage(aSubjectPrincipal)) {
147 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
148 return;
151 aRv = mCache->Clear(this);
152 if (NS_WARN_IF(aRv.Failed())) {
153 return;
156 if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) {
157 OnChange(VoidString(), VoidString(), VoidString());
161 void LocalStorage::OnChange(const nsAString& aKey, const nsAString& aOldValue,
162 const nsAString& aNewValue) {
163 NotifyChange(/* aStorage */ this, StoragePrincipal(), aKey, aOldValue,
164 aNewValue, /* aStorageType */ u"localStorage", mDocumentURI,
165 mIsPrivate, /* aImmediateDispatch */ false);
168 void LocalStorage::ApplyEvent(StorageEvent* aStorageEvent) {
169 MOZ_ASSERT(aStorageEvent);
171 nsAutoString key;
172 nsAutoString old;
173 nsAutoString value;
175 aStorageEvent->GetKey(key);
176 aStorageEvent->GetNewValue(value);
178 // No key means clearing the full storage.
179 if (key.IsVoid()) {
180 MOZ_ASSERT(value.IsVoid());
181 mCache->Clear(this, LocalStorageCache::E10sPropagated);
182 return;
185 // No new value means removing the key.
186 if (value.IsVoid()) {
187 mCache->RemoveItem(this, key, old, LocalStorageCache::E10sPropagated);
188 return;
191 // Otherwise, we set the new value.
192 mCache->SetItem(this, key, value, old, LocalStorageCache::E10sPropagated);
195 void LocalStorage::GetSupportedNames(nsTArray<nsString>& aKeys) {
196 if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) {
197 // return just an empty array
198 aKeys.Clear();
199 return;
202 mCache->GetKeys(this, aKeys);
205 bool LocalStorage::IsForkOf(const Storage* aOther) const {
206 MOZ_ASSERT(aOther);
207 if (aOther->Type() != eLocalStorage) {
208 return false;
211 return mCache == static_cast<const LocalStorage*>(aOther)->mCache;
214 } // namespace dom
215 } // namespace mozilla