Coverage Report

Created: 2018-09-25 14:53

/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