Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/cookie/nsCookie.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "mozilla/Encoding.h"
7
#include "mozilla/dom/ToJSValue.h"
8
#include "nsAutoPtr.h"
9
#include "nsCookie.h"
10
#include <stdlib.h>
11
12
/******************************************************************************
13
 * nsCookie:
14
 * string helper impl
15
 ******************************************************************************/
16
17
// copy aSource strings into contiguous storage provided in aDest1,
18
// providing terminating nulls for each destination string.
19
static inline void
20
StrBlockCopy(const nsACString &aSource1,
21
             const nsACString &aSource2,
22
             const nsACString &aSource3,
23
             const nsACString &aSource4,
24
             char             *&aDest1,
25
             char             *&aDest2,
26
             char             *&aDest3,
27
             char             *&aDest4,
28
             char             *&aDestEnd)
29
0
{
30
0
  size_t len1 = aSource1.Length();
31
0
  memcpy(aDest1, aSource1.BeginReading(), len1);
32
0
  aDest1[len1] = 0;
33
0
34
0
  aDest2 = aDest1 + len1 + 1;
35
0
36
0
  size_t len2 = aSource2.Length();
37
0
  memcpy(aDest2, aSource2.BeginReading(), len2);
38
0
  aDest2[len2] = 0;
39
0
40
0
  aDest3 = aDest2 + len2 + 1;
41
0
42
0
  size_t len3 = aSource3.Length();
43
0
  memcpy(aDest3, aSource3.BeginReading(), len3);
44
0
  aDest3[len3] = 0;
45
0
46
0
  aDest4 = aDest3 + len3 + 1;
47
0
48
0
  size_t len4 = aSource4.Length();
49
0
  memcpy(aDest4, aSource4.BeginReading(), len4);
50
0
  aDest4[len4] = 0;
51
0
52
0
  // Intentionally no + 1 here!
53
0
  aDestEnd = aDest4 + len4;
54
0
}
55
56
/******************************************************************************
57
 * nsCookie:
58
 * creation helper
59
 ******************************************************************************/
60
61
// This is a counter that keeps track of the last used creation time, each time
62
// we create a new nsCookie. This is nominally the time (in microseconds) the
63
// cookie was created, but is guaranteed to be monotonically increasing for
64
// cookies added at runtime after the database has been read in. This is
65
// necessary to enforce ordering among cookies whose creation times would
66
// otherwise overlap, since it's possible two cookies may be created at the same
67
// time, or that the system clock isn't monotonic.
68
static int64_t gLastCreationTime;
69
70
int64_t
71
nsCookie::GenerateUniqueCreationTime(int64_t aCreationTime)
72
0
{
73
0
  // Check if the creation time given to us is greater than the running maximum
74
0
  // (it should always be monotonically increasing).
75
0
  if (aCreationTime > gLastCreationTime) {
76
0
    gLastCreationTime = aCreationTime;
77
0
    return aCreationTime;
78
0
  }
79
0
80
0
  // Make up our own.
81
0
  return ++gLastCreationTime;
82
0
}
83
84
nsCookie *
85
nsCookie::Create(const nsACString &aName,
86
                 const nsACString &aValue,
87
                 const nsACString &aHost,
88
                 const nsACString &aPath,
89
                 int64_t           aExpiry,
90
                 int64_t           aLastAccessed,
91
                 int64_t           aCreationTime,
92
                 bool              aIsSession,
93
                 bool              aIsSecure,
94
                 bool              aIsHttpOnly,
95
                 const OriginAttributes& aOriginAttributes,
96
                 int32_t           aSameSite)
97
0
{
98
0
  // Ensure mValue contains a valid UTF-8 sequence. Otherwise XPConnect will
99
0
  // truncate the string after the first invalid octet.
100
0
  nsAutoCString aUTF8Value;
101
0
  UTF_8_ENCODING->DecodeWithoutBOMHandling(aValue, aUTF8Value);
102
0
103
0
  // find the required string buffer size, adding 4 for the terminating nulls
104
0
  const uint32_t stringLength = aName.Length() + aUTF8Value.Length() +
105
0
                                aHost.Length() + aPath.Length() + 4;
106
0
107
0
  // allocate contiguous space for the nsCookie and its strings -
108
0
  // we store the strings in-line with the nsCookie to save allocations
109
0
  void *place = ::operator new(sizeof(nsCookie) + stringLength);
110
0
  if (!place)
111
0
    return nullptr;
112
0
113
0
  // assign string members
114
0
  char *name, *value, *host, *path, *end;
115
0
  name = static_cast<char *>(place) + sizeof(nsCookie);
116
0
  StrBlockCopy(aName, aUTF8Value, aHost, aPath,
117
0
               name, value, host, path, end);
118
0
119
0
  // If the creationTime given to us is higher than the running maximum, update
120
0
  // our maximum.
121
0
  if (aCreationTime > gLastCreationTime)
122
0
    gLastCreationTime = aCreationTime;
123
0
124
0
  // If aSameSite is not a sensible value, assume strict
125
0
  if (aSameSite < 0 || aSameSite > nsICookie2::SAMESITE_STRICT) {
126
0
    aSameSite = nsICookie2::SAMESITE_STRICT;
127
0
  }
128
0
129
0
  // construct the cookie. placement new, oh yeah!
130
0
  return new (place) nsCookie(name, value, host, path, end,
131
0
                              aExpiry, aLastAccessed, aCreationTime,
132
0
                              aIsSession, aIsSecure, aIsHttpOnly,
133
0
                              aOriginAttributes, aSameSite);
134
0
}
135
136
size_t
137
nsCookie::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
138
0
{
139
0
    // There is no need to measure the sizes of the individual string
140
0
    // members, since the strings are stored in-line with the nsCookie.
141
0
    return aMallocSizeOf(this);
142
0
}
143
144
bool
145
nsCookie::IsStale() const
146
0
{
147
0
  int64_t currentTimeInUsec = PR_Now();
148
0
149
0
  return currentTimeInUsec - LastAccessed() > CookieStaleThreshold() * PR_USEC_PER_SEC;
150
0
}
151
152
/******************************************************************************
153
 * nsCookie:
154
 * xpcom impl
155
 ******************************************************************************/
156
157
// xpcom getters
158
0
NS_IMETHODIMP nsCookie::GetName(nsACString &aName)         { aName = Name();            return NS_OK; }
159
0
NS_IMETHODIMP nsCookie::GetValue(nsACString &aValue)       { aValue = Value();          return NS_OK; }
160
0
NS_IMETHODIMP nsCookie::GetHost(nsACString &aHost)         { aHost = Host();            return NS_OK; }
161
0
NS_IMETHODIMP nsCookie::GetRawHost(nsACString &aHost)      { aHost = RawHost();         return NS_OK; }
162
0
NS_IMETHODIMP nsCookie::GetPath(nsACString &aPath)         { aPath = Path();            return NS_OK; }
163
0
NS_IMETHODIMP nsCookie::GetExpiry(int64_t *aExpiry)        { *aExpiry = Expiry();       return NS_OK; }
164
0
NS_IMETHODIMP nsCookie::GetIsSession(bool *aIsSession)   { *aIsSession = IsSession(); return NS_OK; }
165
0
NS_IMETHODIMP nsCookie::GetIsDomain(bool *aIsDomain)     { *aIsDomain = IsDomain();   return NS_OK; }
166
0
NS_IMETHODIMP nsCookie::GetIsSecure(bool *aIsSecure)     { *aIsSecure = IsSecure();   return NS_OK; }
167
0
NS_IMETHODIMP nsCookie::GetIsHttpOnly(bool *aHttpOnly)   { *aHttpOnly = IsHttpOnly(); return NS_OK; }
168
0
NS_IMETHODIMP nsCookie::GetCreationTime(int64_t *aCreation){ *aCreation = CreationTime(); return NS_OK; }
169
0
NS_IMETHODIMP nsCookie::GetLastAccessed(int64_t *aTime)    { *aTime = LastAccessed();   return NS_OK; }
170
0
NS_IMETHODIMP nsCookie::GetSameSite(int32_t *aSameSite)    { *aSameSite = SameSite();   return NS_OK; }
171
172
NS_IMETHODIMP
173
nsCookie::GetOriginAttributes(JSContext *aCx, JS::MutableHandle<JS::Value> aVal)
174
0
{
175
0
  if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
176
0
    return NS_ERROR_FAILURE;
177
0
  }
178
0
  return NS_OK;
179
0
}
180
181
// compatibility method, for use with the legacy nsICookie interface.
182
// here, expires == 0 denotes a session cookie.
183
NS_IMETHODIMP
184
nsCookie::GetExpires(uint64_t *aExpires)
185
0
{
186
0
  if (IsSession()) {
187
0
    *aExpires = 0;
188
0
  } else {
189
0
    *aExpires = Expiry() > 0 ? Expiry() : 1;
190
0
  }
191
0
  return NS_OK;
192
0
}
193
194
NS_IMPL_ISUPPORTS(nsCookie, nsICookie2, nsICookie)