Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/url/URL.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 "URL.h"
8
#include "URLMainThread.h"
9
#include "URLWorker.h"
10
11
#include "MainThreadUtils.h"
12
#include "mozilla/dom/URLBinding.h"
13
#include "mozilla/dom/BindingUtils.h"
14
#include "nsContentUtils.h"
15
#include "nsIDocument.h"
16
#include "nsIURIMutator.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URL, mParent, mSearchParams)
22
23
NS_IMPL_CYCLE_COLLECTING_ADDREF(URL)
24
NS_IMPL_CYCLE_COLLECTING_RELEASE(URL)
25
26
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URL)
27
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
28
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
29
0
NS_INTERFACE_MAP_END
30
31
JSObject*
32
URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
33
0
{
34
0
  return URL_Binding::Wrap(aCx, this, aGivenProto);
35
0
}
36
37
/* static */ already_AddRefed<URL>
38
URL::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
39
                 const Optional<nsAString>& aBase, ErrorResult& aRv)
40
0
{
41
0
  if (NS_IsMainThread()) {
42
0
    return URLMainThread::Constructor(aGlobal, aURL, aBase, aRv);
43
0
  }
44
0
45
0
  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
46
0
}
47
48
/* static */ already_AddRefed<URL>
49
URL::WorkerConstructor(const GlobalObject& aGlobal, const nsAString& aURL,
50
                       const nsAString& aBase, ErrorResult& aRv)
51
0
{
52
0
  return URLWorker::Constructor(aGlobal, aURL, aBase, aRv);
53
0
}
54
55
void
56
URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
57
                     nsAString& aResult, ErrorResult& aRv)
58
0
{
59
0
  if (NS_IsMainThread()) {
60
0
    URLMainThread::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
61
0
  } else {
62
0
    URLWorker::CreateObjectURL(aGlobal, aBlob, aResult, aRv);
63
0
  }
64
0
}
65
66
void
67
URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
68
                     nsAString& aResult, ErrorResult& aRv)
69
0
{
70
0
  MOZ_ASSERT(NS_IsMainThread());
71
0
  URLMainThread::CreateObjectURL(aGlobal, aSource, aResult, aRv);
72
0
}
73
74
void
75
URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL,
76
                     ErrorResult& aRv)
77
0
{
78
0
  if (NS_IsMainThread()) {
79
0
    URLMainThread::RevokeObjectURL(aGlobal, aURL, aRv);
80
0
  } else {
81
0
    URLWorker::RevokeObjectURL(aGlobal, aURL, aRv);
82
0
  }
83
0
}
84
85
bool
86
URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
87
                ErrorResult& aRv)
88
0
{
89
0
  if (NS_IsMainThread()) {
90
0
    return URLMainThread::IsValidURL(aGlobal, aURL, aRv);
91
0
  }
92
0
  return URLWorker::IsValidURL(aGlobal, aURL, aRv);
93
0
}
94
95
URLSearchParams*
96
URL::SearchParams()
97
0
{
98
0
  CreateSearchParamsIfNeeded();
99
0
  return mSearchParams;
100
0
}
101
102
bool IsChromeURI(nsIURI* aURI)
103
3
{
104
3
  bool isChrome = false;
105
3
  if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)))
106
3
      return isChrome;
107
0
  return false;
108
0
}
109
110
void
111
URL::CreateSearchParamsIfNeeded()
112
0
{
113
0
  if (!mSearchParams) {
114
0
    mSearchParams = new URLSearchParams(mParent, this);
115
0
    UpdateURLSearchParams();
116
0
  }
117
0
}
118
119
void
120
URL::SetSearch(const nsAString& aSearch)
121
0
{
122
0
  SetSearchInternal(aSearch);
123
0
  UpdateURLSearchParams();
124
0
}
125
126
void
127
URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams)
128
0
{
129
0
  MOZ_ASSERT(mSearchParams);
130
0
  MOZ_ASSERT(mSearchParams == aSearchParams);
131
0
132
0
  nsAutoString search;
133
0
  mSearchParams->Serialize(search);
134
0
135
0
  SetSearchInternal(search);
136
0
}
137
138
#define URL_GETTER( value, func ) \
139
0
  MOZ_ASSERT(mURI);               \
140
0
  value.Truncate();               \
141
0
  nsAutoCString tmp;              \
142
0
  nsresult rv = mURI->func(tmp);  \
143
0
  if (NS_SUCCEEDED(rv)) {         \
144
0
    CopyUTF8toUTF16(tmp, value);  \
145
0
  }
146
147
void
148
URL::GetHref(nsAString& aHref) const
149
0
{
150
0
  URL_GETTER(aHref, GetSpec);
151
0
}
152
153
void
154
URL::GetProtocol(nsAString& aProtocol) const
155
0
{
156
0
  URL_GETTER(aProtocol, GetScheme);
157
0
  aProtocol.Append(char16_t(':'));
158
0
}
159
160
void
161
URL::GetUsername(nsAString& aUsername) const
162
0
{
163
0
  URL_GETTER(aUsername, GetUsername);
164
0
}
165
166
void
167
URL::SetUsername(const nsAString& aUsername)
168
0
{
169
0
  MOZ_ASSERT(mURI);
170
0
171
0
  Unused << NS_MutateURI(mURI)
172
0
              .SetUsername(NS_ConvertUTF16toUTF8(aUsername))
173
0
              .Finalize(mURI);
174
0
}
175
176
void
177
URL::GetPassword(nsAString& aPassword) const
178
0
{
179
0
  URL_GETTER(aPassword, GetPassword);
180
0
}
181
182
void
183
URL::SetPassword(const nsAString& aPassword)
184
0
{
185
0
  MOZ_ASSERT(mURI);
186
0
187
0
  Unused << NS_MutateURI(mURI)
188
0
              .SetPassword(NS_ConvertUTF16toUTF8(aPassword))
189
0
              .Finalize(mURI);
190
0
}
191
192
void
193
URL::GetHost(nsAString& aHost) const
194
0
{
195
0
  URL_GETTER(aHost, GetHostPort);
196
0
}
197
198
void
199
URL::SetHost(const nsAString& aHost)
200
0
{
201
0
  MOZ_ASSERT(mURI);
202
0
203
0
  Unused << NS_MutateURI(mURI)
204
0
              .SetHostPort(NS_ConvertUTF16toUTF8(aHost))
205
0
              .Finalize(mURI);
206
0
}
207
208
void
209
URL::GetHostname(nsAString& aHostname) const
210
0
{
211
0
  MOZ_ASSERT(mURI);
212
0
213
0
  aHostname.Truncate();
214
0
  nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname);
215
0
}
216
217
void
218
URL::SetHostname(const nsAString& aHostname)
219
0
{
220
0
  MOZ_ASSERT(mURI);
221
0
222
0
  // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname
223
0
  // The return code is silently ignored
224
0
  mozilla::Unused << NS_MutateURI(mURI)
225
0
                       .SetHost(NS_ConvertUTF16toUTF8(aHostname))
226
0
                       .Finalize(mURI);
227
0
}
228
229
void
230
URL::GetPort(nsAString& aPort) const
231
0
{
232
0
  MOZ_ASSERT(mURI);
233
0
234
0
  aPort.Truncate();
235
0
236
0
  int32_t port;
237
0
  nsresult rv = mURI->GetPort(&port);
238
0
  if (NS_SUCCEEDED(rv) && port != -1) {
239
0
    nsAutoString portStr;
240
0
    portStr.AppendInt(port, 10);
241
0
    aPort.Assign(portStr);
242
0
  }
243
0
}
244
245
void
246
URL::SetPort(const nsAString& aPort)
247
0
{
248
0
  nsresult rv;
249
0
  nsAutoString portStr(aPort);
250
0
  int32_t port = -1;
251
0
252
0
  // nsIURI uses -1 as default value.
253
0
  if (!portStr.IsEmpty()) {
254
0
    port = portStr.ToInteger(&rv);
255
0
    if (NS_FAILED(rv)) {
256
0
      return;
257
0
    }
258
0
  }
259
0
260
0
  Unused << NS_MutateURI(mURI)
261
0
              .SetPort(port)
262
0
              .Finalize(mURI);
263
0
}
264
265
void
266
URL::GetPathname(nsAString& aPathname) const
267
0
{
268
0
  MOZ_ASSERT(mURI);
269
0
270
0
  aPathname.Truncate();
271
0
272
0
  // Do not throw!  Not having a valid URI or URL should result in an empty
273
0
  // string.
274
0
275
0
  nsAutoCString file;
276
0
  nsresult rv = mURI->GetFilePath(file);
277
0
  if (NS_SUCCEEDED(rv)) {
278
0
    CopyUTF8toUTF16(file, aPathname);
279
0
  }
280
0
}
281
282
void
283
URL::SetPathname(const nsAString& aPathname)
284
0
{
285
0
  MOZ_ASSERT(mURI);
286
0
287
0
  // Do not throw!
288
0
289
0
  Unused << NS_MutateURI(mURI)
290
0
              .SetFilePath(NS_ConvertUTF16toUTF8(aPathname))
291
0
              .Finalize(mURI);
292
0
}
293
294
void
295
URL::GetSearch(nsAString& aSearch) const
296
0
{
297
0
  MOZ_ASSERT(mURI);
298
0
299
0
  aSearch.Truncate();
300
0
301
0
  // Do not throw!  Not having a valid URI or URL should result in an empty
302
0
  // string.
303
0
304
0
  nsAutoCString search;
305
0
  nsresult rv;
306
0
307
0
  rv = mURI->GetQuery(search);
308
0
  if (NS_SUCCEEDED(rv) && !search.IsEmpty()) {
309
0
    aSearch.Assign(u'?');
310
0
    AppendUTF8toUTF16(search, aSearch);
311
0
  }
312
0
}
313
314
void
315
URL::GetHash(nsAString& aHash) const
316
0
{
317
0
  MOZ_ASSERT(mURI);
318
0
319
0
  aHash.Truncate();
320
0
321
0
  nsAutoCString ref;
322
0
  nsresult rv = mURI->GetRef(ref);
323
0
  if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
324
0
    aHash.Assign(char16_t('#'));
325
0
    AppendUTF8toUTF16(ref, aHash);
326
0
  }
327
0
}
328
329
void
330
URL::SetHash(const nsAString& aHash)
331
0
{
332
0
  MOZ_ASSERT(mURI);
333
0
334
0
  Unused << NS_MutateURI(mURI)
335
0
              .SetRef(NS_ConvertUTF16toUTF8(aHash))
336
0
              .Finalize(mURI);
337
0
}
338
339
void
340
URL::SetSearchInternal(const nsAString& aSearch)
341
0
{
342
0
  MOZ_ASSERT(mURI);
343
0
344
0
  // Ignore failures to be compatible with NS4.
345
0
346
0
  Unused << NS_MutateURI(mURI)
347
0
              .SetQuery(NS_ConvertUTF16toUTF8(aSearch))
348
0
              .Finalize(mURI);
349
0
}
350
351
void
352
URL::UpdateURLSearchParams()
353
0
{
354
0
  if (!mSearchParams) {
355
0
    return;
356
0
  }
357
0
358
0
  nsAutoCString search;
359
0
  nsresult rv = GetURI()->GetQuery(search);
360
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
361
0
    search.Truncate();
362
0
  }
363
0
364
0
  mSearchParams->ParseInput(search);
365
0
}
366
367
void
368
URL::SetURI(already_AddRefed<nsIURI> aURI)
369
0
{
370
0
  mURI = std::move(aURI);
371
0
  MOZ_ASSERT(mURI);
372
0
}
373
374
nsIURI*
375
URL::GetURI() const
376
0
{
377
0
  MOZ_ASSERT(mURI);
378
0
  return mURI;
379
0
}
380
381
} // namespace dom
382
} // namespace mozilla