Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/storage/SessionStorageManager.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 "SessionStorageManager.h"
8
9
#include "SessionStorage.h"
10
#include "SessionStorageCache.h"
11
#include "StorageUtils.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
using namespace StorageUtils;
17
18
NS_IMPL_ISUPPORTS(SessionStorageManager, nsIDOMStorageManager)
19
20
SessionStorageManager::SessionStorageManager()
21
0
{
22
0
  StorageObserver* observer = StorageObserver::Self();
23
0
  NS_ASSERTION(observer, "No StorageObserver, cannot observe private data delete notifications!");
24
0
25
0
  if (observer) {
26
0
    observer->AddSink(this);
27
0
  }
28
0
}
29
30
SessionStorageManager::~SessionStorageManager()
31
0
{
32
0
  StorageObserver* observer = StorageObserver::Self();
33
0
  if (observer) {
34
0
    observer->RemoveSink(this);
35
0
  }
36
0
}
37
38
NS_IMETHODIMP
39
SessionStorageManager::PrecacheStorage(nsIPrincipal* aPrincipal,
40
                                       Storage** aRetval)
41
0
{
42
0
  // Nothing to preload.
43
0
  return NS_OK;
44
0
}
45
46
NS_IMETHODIMP
47
SessionStorageManager::CreateStorage(mozIDOMWindow* aWindow,
48
                                     nsIPrincipal* aPrincipal,
49
                                     const nsAString& aDocumentURI,
50
                                     bool aPrivate,
51
                                     Storage** aRetval)
52
0
{
53
0
  nsAutoCString originKey;
54
0
  nsAutoCString originAttributes;
55
0
  nsresult rv = GenerateOriginKey(aPrincipal, originAttributes, originKey);
56
0
  if (NS_FAILED(rv)) {
57
0
    return NS_ERROR_NOT_AVAILABLE;
58
0
  }
59
0
60
0
  OriginKeyHashTable* table;
61
0
  if (!mOATable.Get(originAttributes, &table)) {
62
0
    table = new OriginKeyHashTable();
63
0
    mOATable.Put(originAttributes, table);
64
0
  }
65
0
66
0
  RefPtr<SessionStorageCache> cache;
67
0
  if (!table->Get(originKey, getter_AddRefs(cache))) {
68
0
    cache = new SessionStorageCache();
69
0
    table->Put(originKey, cache);
70
0
  }
71
0
72
0
  nsCOMPtr<nsPIDOMWindowInner> inner = nsPIDOMWindowInner::From(aWindow);
73
0
74
0
  RefPtr<SessionStorage> storage =
75
0
    new SessionStorage(inner, aPrincipal, cache, this, aDocumentURI, aPrivate);
76
0
77
0
  storage.forget(aRetval);
78
0
  return NS_OK;
79
0
}
80
81
NS_IMETHODIMP
82
SessionStorageManager::GetStorage(mozIDOMWindow* aWindow,
83
                                  nsIPrincipal* aPrincipal,
84
                                  bool aPrivate,
85
                                  Storage** aRetval)
86
0
{
87
0
  *aRetval = nullptr;
88
0
89
0
  nsAutoCString originKey;
90
0
  nsAutoCString originAttributes;
91
0
  nsresult rv = GenerateOriginKey(aPrincipal, originAttributes, originKey);
92
0
  if (NS_FAILED(rv)) {
93
0
    return rv;
94
0
  }
95
0
96
0
  OriginKeyHashTable* table;
97
0
  if (!mOATable.Get(originAttributes, &table)) {
98
0
    return NS_OK;
99
0
  }
100
0
101
0
  RefPtr<SessionStorageCache> cache;
102
0
  if (!table->Get(originKey, getter_AddRefs(cache))) {
103
0
    return NS_OK;
104
0
  }
105
0
106
0
  nsCOMPtr<nsPIDOMWindowInner> inner = nsPIDOMWindowInner::From(aWindow);
107
0
108
0
  RefPtr<SessionStorage> storage =
109
0
    new SessionStorage(inner, aPrincipal, cache, this, EmptyString(), aPrivate);
110
0
111
0
  storage.forget(aRetval);
112
0
  return NS_OK;
113
0
}
114
115
NS_IMETHODIMP
116
SessionStorageManager::CloneStorage(Storage* aStorage)
117
0
{
118
0
  if (NS_WARN_IF(!aStorage)) {
119
0
    return NS_ERROR_UNEXPECTED;
120
0
  }
121
0
122
0
  if (aStorage->Type() != Storage::eSessionStorage) {
123
0
    return NS_ERROR_UNEXPECTED;
124
0
  }
125
0
126
0
  nsAutoCString originKey;
127
0
  nsAutoCString originAttributes;
128
0
  nsresult rv = GenerateOriginKey(aStorage->Principal(), originAttributes,
129
0
                                  originKey);
130
0
  if (NS_FAILED(rv)) {
131
0
    return rv;
132
0
  }
133
0
134
0
  OriginKeyHashTable* table;
135
0
  if (!mOATable.Get(originAttributes, &table)) {
136
0
    table = new OriginKeyHashTable();
137
0
    mOATable.Put(originAttributes, table);
138
0
  }
139
0
140
0
  RefPtr<SessionStorageCache> cache;
141
0
  if (table->Get(originKey, getter_AddRefs(cache))) {
142
0
    // Do not replace an existing sessionStorage.
143
0
    return NS_OK;
144
0
  }
145
0
146
0
  cache = static_cast<SessionStorage*>(aStorage)->Cache()->Clone();
147
0
  MOZ_ASSERT(cache);
148
0
149
0
  table->Put(originKey, cache);
150
0
  return NS_OK;
151
0
}
152
153
NS_IMETHODIMP
154
SessionStorageManager::CheckStorage(nsIPrincipal* aPrincipal,
155
                                    Storage* aStorage,
156
                                    bool* aRetval)
157
0
{
158
0
  if (NS_WARN_IF(!aStorage)) {
159
0
    return NS_ERROR_UNEXPECTED;
160
0
  }
161
0
162
0
  if (!aPrincipal) {
163
0
    return NS_ERROR_NOT_AVAILABLE;
164
0
  }
165
0
166
0
  nsAutoCString originKey;
167
0
  nsAutoCString originAttributes;
168
0
  nsresult rv = GenerateOriginKey(aPrincipal, originAttributes, originKey);
169
0
  if (NS_FAILED(rv)) {
170
0
    return rv;
171
0
  }
172
0
173
0
  *aRetval = false;
174
0
175
0
  OriginKeyHashTable* table;
176
0
  if (!mOATable.Get(originAttributes, &table)) {
177
0
    return NS_OK;
178
0
  }
179
0
180
0
  RefPtr<SessionStorageCache> cache;
181
0
  if (!table->Get(originKey, getter_AddRefs(cache))) {
182
0
    return NS_OK;
183
0
  }
184
0
185
0
  if (aStorage->Type() != Storage::eSessionStorage) {
186
0
    return NS_OK;
187
0
  }
188
0
189
0
  RefPtr<SessionStorage> sessionStorage =
190
0
    static_cast<SessionStorage*>(aStorage);
191
0
  if (sessionStorage->Cache() != cache) {
192
0
    return NS_OK;
193
0
  }
194
0
195
0
  if (!StorageUtils::PrincipalsEqual(aStorage->Principal(), aPrincipal)) {
196
0
    return NS_OK;
197
0
  }
198
0
199
0
  *aRetval = true;
200
0
  return NS_OK;
201
0
}
202
203
void
204
SessionStorageManager::ClearStorages(ClearStorageType aType,
205
                                     const OriginAttributesPattern& aPattern,
206
                                     const nsACString& aOriginScope)
207
0
{
208
0
  for (auto iter1 = mOATable.Iter(); !iter1.Done(); iter1.Next()) {
209
0
    OriginAttributes oa;
210
0
    DebugOnly<bool> ok = oa.PopulateFromSuffix(iter1.Key());
211
0
    MOZ_ASSERT(ok);
212
0
    if (!aPattern.Matches(oa)) {
213
0
      // This table doesn't match the given origin attributes pattern
214
0
      continue;
215
0
    }
216
0
217
0
    OriginKeyHashTable* table = iter1.Data();
218
0
    for (auto iter2 = table->Iter(); !iter2.Done(); iter2.Next()) {
219
0
      if (aOriginScope.IsEmpty() ||
220
0
          StringBeginsWith(iter2.Key(), aOriginScope)) {
221
0
        if (aType == eAll) {
222
0
          iter2.Data()->Clear(SessionStorageCache::eDefaultSetType, false);
223
0
          iter2.Data()->Clear(SessionStorageCache::eSessionSetType, false);
224
0
        } else {
225
0
          MOZ_ASSERT(aType == eSessionOnly);
226
0
          iter2.Data()->Clear(SessionStorageCache::eSessionSetType, false);
227
0
        }
228
0
      }
229
0
    }
230
0
  }
231
0
}
232
233
nsresult
234
SessionStorageManager::Observe(const char* aTopic,
235
                               const nsAString& aOriginAttributesPattern,
236
                               const nsACString& aOriginScope)
237
0
{
238
0
  OriginAttributesPattern pattern;
239
0
  if (!pattern.Init(aOriginAttributesPattern)) {
240
0
    NS_ERROR("Cannot parse origin attributes pattern");
241
0
    return NS_ERROR_FAILURE;
242
0
  }
243
0
244
0
  // Clear everything, caches + database
245
0
  if (!strcmp(aTopic, "cookie-cleared")) {
246
0
    ClearStorages(eAll, pattern, EmptyCString());
247
0
    return NS_OK;
248
0
  }
249
0
250
0
  // Clear from caches everything that has been stored
251
0
  // while in session-only mode
252
0
  if (!strcmp(aTopic, "session-only-cleared")) {
253
0
    ClearStorages(eSessionOnly, pattern, aOriginScope);
254
0
    return NS_OK;
255
0
  }
256
0
257
0
  // Clear everything (including so and pb data) from caches and database
258
0
  // for the gived domain and subdomains.
259
0
  if (!strcmp(aTopic, "domain-data-cleared")) {
260
0
    ClearStorages(eAll, pattern, aOriginScope);
261
0
    return NS_OK;
262
0
  }
263
0
264
0
  if (!strcmp(aTopic, "profile-change")) {
265
0
    // For case caches are still referenced - clear them completely
266
0
    ClearStorages(eAll, pattern, EmptyCString());
267
0
    mOATable.Clear();
268
0
    return NS_OK;
269
0
  }
270
0
271
0
  return NS_OK;
272
0
}
273
274
} // dom namespace
275
} // mozilla namespace