/src/mozilla-central/dom/storage/SessionStorage.cpp
Line | Count | Source (jump to first uncovered line) |
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 "SessionStorage.h" |
8 | | #include "SessionStorageCache.h" |
9 | | #include "SessionStorageManager.h" |
10 | | |
11 | | #include "mozilla/dom/StorageBinding.h" |
12 | | #include "mozilla/Preferences.h" |
13 | | #include "nsContentUtils.h" |
14 | | #include "nsIPrincipal.h" |
15 | | #include "nsPIDOMWindow.h" |
16 | | |
17 | 0 | #define DATASET IsSessionOnly() \ |
18 | 0 | ? SessionStorageCache::eSessionSetType \ |
19 | 0 | : SessionStorageCache::eDefaultSetType |
20 | | |
21 | | namespace mozilla { |
22 | | namespace dom { |
23 | | |
24 | | NS_IMPL_CYCLE_COLLECTION_INHERITED(SessionStorage, Storage, mManager); |
25 | | |
26 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SessionStorage) |
27 | 0 | NS_INTERFACE_MAP_END_INHERITING(Storage) |
28 | | |
29 | | NS_IMPL_ADDREF_INHERITED(SessionStorage, Storage) |
30 | | NS_IMPL_RELEASE_INHERITED(SessionStorage, Storage) |
31 | | |
32 | | SessionStorage::SessionStorage(nsPIDOMWindowInner* aWindow, |
33 | | nsIPrincipal* aPrincipal, |
34 | | SessionStorageCache* aCache, |
35 | | SessionStorageManager* aManager, |
36 | | const nsAString& aDocumentURI, |
37 | | bool aIsPrivate) |
38 | | : Storage(aWindow, aPrincipal) |
39 | | , mCache(aCache) |
40 | | , mManager(aManager) |
41 | | , mDocumentURI(aDocumentURI) |
42 | | , mIsPrivate(aIsPrivate) |
43 | 0 | { |
44 | 0 | MOZ_ASSERT(aCache); |
45 | 0 | } |
46 | | |
47 | | SessionStorage::~SessionStorage() |
48 | 0 | { |
49 | 0 | } |
50 | | |
51 | | already_AddRefed<SessionStorage> |
52 | | SessionStorage::Clone() const |
53 | 0 | { |
54 | 0 | RefPtr<SessionStorage> storage = |
55 | 0 | new SessionStorage(GetParentObject(), Principal(), mCache, mManager, |
56 | 0 | mDocumentURI, mIsPrivate); |
57 | 0 | return storage.forget(); |
58 | 0 | } |
59 | | |
60 | | int64_t |
61 | | SessionStorage::GetOriginQuotaUsage() const |
62 | 0 | { |
63 | 0 | return mCache->GetOriginQuotaUsage(DATASET); |
64 | 0 | } |
65 | | |
66 | | uint32_t |
67 | | SessionStorage::GetLength(nsIPrincipal& aSubjectPrincipal, |
68 | | ErrorResult& aRv) |
69 | 0 | { |
70 | 0 | if (!CanUseStorage(aSubjectPrincipal)) { |
71 | 0 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); |
72 | 0 | return 0; |
73 | 0 | } |
74 | 0 | |
75 | 0 | return mCache->Length(DATASET); |
76 | 0 | } |
77 | | |
78 | | void |
79 | | SessionStorage::Key(uint32_t aIndex, nsAString& aResult, |
80 | | nsIPrincipal& aSubjectPrincipal, |
81 | | ErrorResult& aRv) |
82 | 0 | { |
83 | 0 | if (!CanUseStorage(aSubjectPrincipal)) { |
84 | 0 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); |
85 | 0 | return; |
86 | 0 | } |
87 | 0 | |
88 | 0 | mCache->Key(DATASET, aIndex, aResult); |
89 | 0 | } |
90 | | |
91 | | void |
92 | | SessionStorage::GetItem(const nsAString& aKey, nsAString& aResult, |
93 | | nsIPrincipal& aSubjectPrincipal, |
94 | | ErrorResult& aRv) |
95 | 0 | { |
96 | 0 | if (!CanUseStorage(aSubjectPrincipal)) { |
97 | 0 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); |
98 | 0 | return; |
99 | 0 | } |
100 | 0 | |
101 | 0 | mCache->GetItem(DATASET, aKey, aResult); |
102 | 0 | } |
103 | | |
104 | | void |
105 | | SessionStorage::GetSupportedNames(nsTArray<nsString>& aKeys) |
106 | 0 | { |
107 | 0 | if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) { |
108 | 0 | // return just an empty array |
109 | 0 | aKeys.Clear(); |
110 | 0 | return; |
111 | 0 | } |
112 | 0 | |
113 | 0 | mCache->GetKeys(DATASET, aKeys); |
114 | 0 | } |
115 | | |
116 | | void |
117 | | SessionStorage::SetItem(const nsAString& aKey, const nsAString& aValue, |
118 | | nsIPrincipal& aSubjectPrincipal, |
119 | | ErrorResult& aRv) |
120 | 0 | { |
121 | 0 | if (!CanUseStorage(aSubjectPrincipal)) { |
122 | 0 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); |
123 | 0 | return; |
124 | 0 | } |
125 | 0 | |
126 | 0 | nsString oldValue; |
127 | 0 | nsresult rv = mCache->SetItem(DATASET, aKey, aValue, oldValue); |
128 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
129 | 0 | aRv.Throw(rv); |
130 | 0 | return; |
131 | 0 | } |
132 | 0 | |
133 | 0 | if (rv == NS_SUCCESS_DOM_NO_OPERATION) { |
134 | 0 | return; |
135 | 0 | } |
136 | 0 | |
137 | 0 | BroadcastChangeNotification(aKey, oldValue, aValue); |
138 | 0 | } |
139 | | |
140 | | void |
141 | | SessionStorage::RemoveItem(const nsAString& aKey, |
142 | | nsIPrincipal& aSubjectPrincipal, |
143 | | ErrorResult& aRv) |
144 | 0 | { |
145 | 0 | if (!CanUseStorage(aSubjectPrincipal)) { |
146 | 0 | aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); |
147 | 0 | return; |
148 | 0 | } |
149 | 0 | |
150 | 0 | nsString oldValue; |
151 | 0 | nsresult rv = mCache->RemoveItem(DATASET, aKey, oldValue); |
152 | 0 | MOZ_ASSERT(NS_SUCCEEDED(rv)); |
153 | 0 |
|
154 | 0 | if (rv == NS_SUCCESS_DOM_NO_OPERATION) { |
155 | 0 | return; |
156 | 0 | } |
157 | 0 | |
158 | 0 | BroadcastChangeNotification(aKey, oldValue, VoidString()); |
159 | 0 | } |
160 | | |
161 | | void |
162 | | SessionStorage::Clear(nsIPrincipal& aSubjectPrincipal, |
163 | | ErrorResult& aRv) |
164 | 0 | { |
165 | 0 | uint32_t length = GetLength(aSubjectPrincipal, aRv); |
166 | 0 | if (!length) { |
167 | 0 | return; |
168 | 0 | } |
169 | 0 | |
170 | 0 | mCache->Clear(DATASET); |
171 | 0 | BroadcastChangeNotification(VoidString(), VoidString(), VoidString()); |
172 | 0 | } |
173 | | |
174 | | void |
175 | | SessionStorage::BroadcastChangeNotification(const nsAString& aKey, |
176 | | const nsAString& aOldValue, |
177 | | const nsAString& aNewValue) |
178 | 0 | { |
179 | 0 | NotifyChange(this, Principal(), aKey, aOldValue, aNewValue, u"sessionStorage", |
180 | 0 | mDocumentURI, mIsPrivate, false); |
181 | 0 | } |
182 | | |
183 | | bool |
184 | | SessionStorage::IsForkOf(const Storage* aOther) const |
185 | 0 | { |
186 | 0 | MOZ_ASSERT(aOther); |
187 | 0 | if (aOther->Type() != eSessionStorage) { |
188 | 0 | return false; |
189 | 0 | } |
190 | 0 | |
191 | 0 | return mCache == static_cast<const SessionStorage*>(aOther)->mCache; |
192 | 0 | } |
193 | | |
194 | | } // dom namespace |
195 | | } // mozilla namespace |