Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/nsSimpleURI.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; 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/DebugOnly.h"
7
8
#undef LOG
9
#include "IPCMessageUtils.h"
10
11
#include "nsSimpleURI.h"
12
#include "nscore.h"
13
#include "nsString.h"
14
#include "plstr.h"
15
#include "nsURLHelper.h"
16
#include "nsNetCID.h"
17
#include "nsIObjectInputStream.h"
18
#include "nsIObjectOutputStream.h"
19
#include "nsEscape.h"
20
#include "nsError.h"
21
#include "nsIIPCSerializableURI.h"
22
#include "mozilla/MemoryReporting.h"
23
#include "mozilla/ipc/URIUtils.h"
24
#include "nsIURIMutator.h"
25
26
using namespace mozilla::ipc;
27
28
namespace mozilla {
29
namespace net {
30
31
static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
32
                     NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
33
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
34
35
/* static */ already_AddRefed<nsSimpleURI>
36
nsSimpleURI::From(nsIURI* aURI)
37
0
{
38
0
    RefPtr<nsSimpleURI> uri;
39
0
    nsresult rv = aURI->QueryInterface(kThisSimpleURIImplementationCID,
40
0
                                       getter_AddRefs(uri));
41
0
    if (NS_FAILED(rv)) {
42
0
        return nullptr;
43
0
    }
44
0
45
0
    return uri.forget();
46
0
}
47
48
////////////////////////////////////////////////////////////////////////////////
49
// nsSimpleURI methods:
50
51
nsSimpleURI::nsSimpleURI()
52
    : mIsRefValid(false)
53
    , mIsQueryValid(false)
54
1.92M
{
55
1.92M
}
56
57
NS_IMPL_ADDREF(nsSimpleURI)
58
NS_IMPL_RELEASE(nsSimpleURI)
59
17.7M
NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
60
17.7M
NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable,
61
17.7M
                   nsIClassInfo, nsIIPCSerializableURI)
62
17.7M
NS_INTERFACE_TABLE_TO_MAP_SEGUE
63
11.2M
  if (aIID.Equals(kThisSimpleURIImplementationCID))
64
0
    foundInterface = static_cast<nsIURI*>(this);
65
11.2M
  else
66
11.2M
  NS_INTERFACE_MAP_ENTRY(nsISizeOf)
67
11.2M
NS_INTERFACE_MAP_END
68
69
////////////////////////////////////////////////////////////////////////////////
70
// nsISerializable methods:
71
72
NS_IMETHODIMP
73
nsSimpleURI::Read(nsIObjectInputStream *aStream)
74
0
{
75
0
    MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
76
0
    return NS_ERROR_NOT_IMPLEMENTED;
77
0
}
78
79
nsresult
80
nsSimpleURI::ReadPrivate(nsIObjectInputStream *aStream)
81
0
{
82
0
    nsresult rv;
83
0
84
0
    bool isMutable;
85
0
    rv = aStream->ReadBoolean(&isMutable);
86
0
    if (NS_FAILED(rv)) return rv;
87
0
    Unused << isMutable;
88
0
89
0
    rv = aStream->ReadCString(mScheme);
90
0
    if (NS_FAILED(rv)) return rv;
91
0
92
0
    rv = aStream->ReadCString(mPath);
93
0
    if (NS_FAILED(rv)) return rv;
94
0
95
0
    bool isRefValid;
96
0
    rv = aStream->ReadBoolean(&isRefValid);
97
0
    if (NS_FAILED(rv)) return rv;
98
0
    mIsRefValid = isRefValid;
99
0
100
0
    if (isRefValid) {
101
0
        rv = aStream->ReadCString(mRef);
102
0
        if (NS_FAILED(rv)) return rv;
103
0
    } else {
104
0
        mRef.Truncate(); // invariant: mRef should be empty when it's not valid
105
0
    }
106
0
107
0
    bool isQueryValid;
108
0
    rv = aStream->ReadBoolean(&isQueryValid);
109
0
    if (NS_FAILED(rv)) return rv;
110
0
    mIsQueryValid = isQueryValid;
111
0
112
0
    if (isQueryValid) {
113
0
        rv = aStream->ReadCString(mQuery);
114
0
        if (NS_FAILED(rv)) return rv;
115
0
    } else {
116
0
        mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
117
0
    }
118
0
119
0
    return NS_OK;
120
0
}
121
122
NS_IMETHODIMP
123
nsSimpleURI::Write(nsIObjectOutputStream* aStream)
124
0
{
125
0
    nsresult rv;
126
0
127
0
    rv = aStream->WriteBoolean(false); // former mMutable
128
0
    if (NS_FAILED(rv)) return rv;
129
0
130
0
    rv = aStream->WriteStringZ(mScheme.get());
131
0
    if (NS_FAILED(rv)) return rv;
132
0
133
0
    rv = aStream->WriteStringZ(mPath.get());
134
0
    if (NS_FAILED(rv)) return rv;
135
0
136
0
    rv = aStream->WriteBoolean(mIsRefValid);
137
0
    if (NS_FAILED(rv)) return rv;
138
0
139
0
    if (mIsRefValid) {
140
0
        rv = aStream->WriteStringZ(mRef.get());
141
0
        if (NS_FAILED(rv)) return rv;
142
0
    }
143
0
144
0
    rv = aStream->WriteBoolean(mIsQueryValid);
145
0
    if (NS_FAILED(rv)) return rv;
146
0
147
0
    if (mIsQueryValid) {
148
0
        rv = aStream->WriteStringZ(mQuery.get());
149
0
        if (NS_FAILED(rv)) return rv;
150
0
    }
151
0
152
0
    return NS_OK;
153
0
}
154
155
////////////////////////////////////////////////////////////////////////////////
156
// nsIIPCSerializableURI methods:
157
158
void
159
nsSimpleURI::Serialize(URIParams& aParams)
160
0
{
161
0
    SimpleURIParams params;
162
0
163
0
    params.scheme() = mScheme;
164
0
    params.path() = mPath;
165
0
166
0
    if (mIsRefValid) {
167
0
      params.ref() = mRef;
168
0
    } else {
169
0
      params.ref().SetIsVoid(true);
170
0
    }
171
0
172
0
    if (mIsQueryValid) {
173
0
      params.query() = mQuery;
174
0
    } else {
175
0
      params.query().SetIsVoid(true);
176
0
    }
177
0
178
0
    aParams = params;
179
0
}
180
181
bool
182
nsSimpleURI::Deserialize(const URIParams& aParams)
183
0
{
184
0
    if (aParams.type() != URIParams::TSimpleURIParams) {
185
0
        NS_ERROR("Received unknown parameters from the other process!");
186
0
        return false;
187
0
    }
188
0
189
0
    const SimpleURIParams& params = aParams.get_SimpleURIParams();
190
0
191
0
    mScheme = params.scheme();
192
0
    mPath = params.path();
193
0
194
0
    if (params.ref().IsVoid()) {
195
0
        mRef.Truncate();
196
0
        mIsRefValid = false;
197
0
    } else {
198
0
        mRef = params.ref();
199
0
        mIsRefValid = true;
200
0
    }
201
0
202
0
    if (params.query().IsVoid()) {
203
0
        mQuery.Truncate();
204
0
        mIsQueryValid = false;
205
0
    } else {
206
0
        mQuery = params.query();
207
0
        mIsQueryValid = true;
208
0
    }
209
0
210
0
    return true;
211
0
}
212
213
////////////////////////////////////////////////////////////////////////////////
214
// nsIURI methods:
215
216
NS_IMETHODIMP
217
nsSimpleURI::GetSpec(nsACString &result)
218
0
{
219
0
    if (!result.Assign(mScheme, fallible) ||
220
0
        !result.Append(NS_LITERAL_CSTRING(":"), fallible) ||
221
0
        !result.Append(mPath, fallible)) {
222
0
        return NS_ERROR_OUT_OF_MEMORY;
223
0
    }
224
0
225
0
    if (mIsQueryValid) {
226
0
        if (!result.Append(NS_LITERAL_CSTRING("?"), fallible) ||
227
0
            !result.Append(mQuery, fallible)) {
228
0
            return NS_ERROR_OUT_OF_MEMORY;
229
0
        }
230
0
    } else {
231
0
        MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
232
0
    }
233
0
234
0
    if (mIsRefValid) {
235
0
        if (!result.Append(NS_LITERAL_CSTRING("#"), fallible) ||
236
0
            !result.Append(mRef, fallible)) {
237
0
            return NS_ERROR_OUT_OF_MEMORY;
238
0
        }
239
0
    } else {
240
0
        MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
241
0
    }
242
0
243
0
    return NS_OK;
244
0
}
245
246
// result may contain unescaped UTF-8 characters
247
NS_IMETHODIMP
248
nsSimpleURI::GetSpecIgnoringRef(nsACString &result)
249
0
{
250
0
    result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
251
0
    if (mIsQueryValid) {
252
0
        result += NS_LITERAL_CSTRING("?") + mQuery;
253
0
    }
254
0
    return NS_OK;
255
0
}
256
257
NS_IMETHODIMP
258
nsSimpleURI::GetDisplaySpec(nsACString &aUnicodeSpec)
259
0
{
260
0
    return GetSpec(aUnicodeSpec);
261
0
}
262
263
NS_IMETHODIMP
264
nsSimpleURI::GetDisplayHostPort(nsACString &aUnicodeHostPort)
265
0
{
266
0
    return GetHostPort(aUnicodeHostPort);
267
0
}
268
269
NS_IMETHODIMP
270
nsSimpleURI::GetDisplayHost(nsACString &aUnicodeHost)
271
0
{
272
0
    return GetHost(aUnicodeHost);
273
0
}
274
275
NS_IMETHODIMP
276
nsSimpleURI::GetDisplayPrePath(nsACString &aPrePath)
277
0
{
278
0
    return GetPrePath(aPrePath);
279
0
}
280
281
NS_IMETHODIMP
282
nsSimpleURI::GetHasRef(bool *result)
283
0
{
284
0
    *result = mIsRefValid;
285
0
    return NS_OK;
286
0
}
287
288
nsresult
289
nsSimpleURI::SetSpecInternal(const nsACString &aSpec)
290
1.92M
{
291
1.92M
    nsresult rv = net_ExtractURLScheme(aSpec, mScheme);
292
1.92M
    if (NS_FAILED(rv)) {
293
91
        return rv;
294
91
    }
295
1.92M
296
1.92M
    nsAutoCString spec;
297
1.92M
    rv = net_FilterAndEscapeURI(aSpec, esc_OnlyNonASCII, spec);
298
1.92M
    if (NS_FAILED(rv)) {
299
0
        return rv;
300
0
    }
301
1.92M
302
1.92M
    int32_t colonPos = spec.FindChar(':');
303
1.92M
    MOZ_ASSERT(colonPos != kNotFound, "A colon should be in this string");
304
1.92M
    // This sets mPath, mQuery and mRef.
305
1.92M
    return SetPathQueryRefEscaped(Substring(spec, colonPos + 1),
306
1.92M
                                  /* aNeedsEscape = */ false);
307
1.92M
}
308
309
NS_IMETHODIMP
310
nsSimpleURI::GetScheme(nsACString &result)
311
0
{
312
0
    result = mScheme;
313
0
    return NS_OK;
314
0
}
315
316
nsresult
317
nsSimpleURI::SetScheme(const nsACString &scheme)
318
0
{
319
0
    const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
320
0
    if (!net_IsValidScheme(flat)) {
321
0
        NS_WARNING("the given url scheme contains invalid characters");
322
0
        return NS_ERROR_MALFORMED_URI;
323
0
    }
324
0
325
0
    mScheme = scheme;
326
0
    ToLowerCase(mScheme);
327
0
    return NS_OK;
328
0
}
329
330
NS_IMETHODIMP
331
nsSimpleURI::GetPrePath(nsACString &result)
332
0
{
333
0
    result = mScheme + NS_LITERAL_CSTRING(":");
334
0
    return NS_OK;
335
0
}
336
337
NS_IMETHODIMP
338
nsSimpleURI::GetUserPass(nsACString &result)
339
0
{
340
0
    return NS_ERROR_FAILURE;
341
0
}
342
343
nsresult
344
nsSimpleURI::SetUserPass(const nsACString &userPass)
345
0
{
346
0
    return NS_ERROR_FAILURE;
347
0
}
348
349
NS_IMETHODIMP
350
nsSimpleURI::GetUsername(nsACString &result)
351
0
{
352
0
    return NS_ERROR_FAILURE;
353
0
}
354
355
nsresult
356
nsSimpleURI::SetUsername(const nsACString &userName)
357
0
{
358
0
    return NS_ERROR_FAILURE;
359
0
}
360
361
NS_IMETHODIMP
362
nsSimpleURI::GetPassword(nsACString &result)
363
0
{
364
0
    return NS_ERROR_FAILURE;
365
0
}
366
367
nsresult
368
nsSimpleURI::SetPassword(const nsACString &password)
369
0
{
370
0
    return NS_ERROR_FAILURE;
371
0
}
372
373
NS_IMETHODIMP
374
nsSimpleURI::GetHostPort(nsACString &result)
375
0
{
376
0
    // Note: Audit all callers before changing this to return an empty
377
0
    // string -- CAPS and UI code may depend on this throwing.
378
0
    // Note: If this is changed, change GetAsciiHostPort as well.
379
0
    return NS_ERROR_FAILURE;
380
0
}
381
382
nsresult
383
nsSimpleURI::SetHostPort(const nsACString &result)
384
0
{
385
0
    return NS_ERROR_FAILURE;
386
0
}
387
388
NS_IMETHODIMP
389
nsSimpleURI::GetHost(nsACString &result)
390
0
{
391
0
    // Note: Audit all callers before changing this to return an empty
392
0
    // string -- CAPS and UI code depend on this throwing.
393
0
    return NS_ERROR_FAILURE;
394
0
}
395
396
nsresult
397
nsSimpleURI::SetHost(const nsACString &host)
398
0
{
399
0
    return NS_ERROR_FAILURE;
400
0
}
401
402
NS_IMETHODIMP
403
nsSimpleURI::GetPort(int32_t *result)
404
0
{
405
0
    // Note: Audit all callers before changing this to return an empty
406
0
    // string -- CAPS and UI code may depend on this throwing.
407
0
    return NS_ERROR_FAILURE;
408
0
}
409
410
nsresult
411
nsSimpleURI::SetPort(int32_t port)
412
0
{
413
0
    return NS_ERROR_FAILURE;
414
0
}
415
416
NS_IMETHODIMP
417
nsSimpleURI::GetPathQueryRef(nsACString &result)
418
4.94k
{
419
4.94k
    result = mPath;
420
4.94k
    if (mIsQueryValid) {
421
1.34k
        result += NS_LITERAL_CSTRING("?") + mQuery;
422
1.34k
    }
423
4.94k
    if (mIsRefValid) {
424
94
        result += NS_LITERAL_CSTRING("#") + mRef;
425
94
    }
426
4.94k
427
4.94k
    return NS_OK;
428
4.94k
}
429
430
nsresult
431
nsSimpleURI::SetPathQueryRef(const nsACString &aPath)
432
0
{
433
0
    return SetPathQueryRefEscaped(aPath, true);
434
0
}
435
nsresult
436
nsSimpleURI::SetPathQueryRefEscaped(const nsACString &aPath, bool aNeedsEscape)
437
1.92M
{
438
1.92M
    nsresult rv;
439
1.92M
    nsAutoCString path;
440
1.92M
    if (aNeedsEscape) {
441
0
        rv = NS_EscapeURL(aPath, esc_OnlyNonASCII, path, fallible);
442
0
        if (NS_FAILED(rv)) {
443
0
          return rv;
444
0
        }
445
1.92M
    } else {
446
1.92M
        if (!path.Assign(aPath, fallible)) {
447
0
            return NS_ERROR_OUT_OF_MEMORY;
448
0
        }
449
1.92M
    }
450
1.92M
451
1.92M
    int32_t queryPos = path.FindChar('?');
452
1.92M
    int32_t hashPos = path.FindChar('#');
453
1.92M
454
1.92M
    if (queryPos != kNotFound && hashPos != kNotFound && hashPos < queryPos) {
455
287
        queryPos = kNotFound;
456
287
    }
457
1.92M
458
1.92M
    nsAutoCString query;
459
1.92M
    if (queryPos != kNotFound) {
460
2.18k
        query.Assign(Substring(path, queryPos));
461
2.18k
        path.Truncate(queryPos);
462
2.18k
    }
463
1.92M
464
1.92M
    nsAutoCString hash;
465
1.92M
    if (hashPos != kNotFound) {
466
2.24k
        if (query.IsEmpty()) {
467
1.99k
            hash.Assign(Substring(path, hashPos));
468
1.99k
            path.Truncate(hashPos);
469
1.99k
        } else {
470
249
            // We have to search the hash character in the query
471
249
            hashPos = query.FindChar('#');
472
249
            hash.Assign(Substring(query, hashPos));
473
249
            query.Truncate(hashPos);
474
249
        }
475
2.24k
    }
476
1.92M
477
1.92M
    mIsQueryValid = false;
478
1.92M
    mQuery.Truncate();
479
1.92M
480
1.92M
    mIsRefValid = false;
481
1.92M
    mRef.Truncate();
482
1.92M
483
1.92M
    // The path
484
1.92M
    if (!mPath.Assign(path, fallible)) {
485
0
        return NS_ERROR_OUT_OF_MEMORY;
486
0
    }
487
1.92M
488
1.92M
    rv = SetQuery(query);
489
1.92M
    if (NS_FAILED(rv)) {
490
0
        return rv;
491
0
    }
492
1.92M
493
1.92M
    return SetRef(hash);
494
1.92M
}
495
496
NS_IMETHODIMP
497
nsSimpleURI::GetRef(nsACString &result)
498
0
{
499
0
    if (!mIsRefValid) {
500
0
        MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
501
0
        result.Truncate();
502
0
    } else {
503
0
        result = mRef;
504
0
    }
505
0
506
0
    return NS_OK;
507
0
}
508
509
// NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
510
// string (and will result in .spec and .path having a terminal #).
511
nsresult
512
nsSimpleURI::SetRef(const nsACString &aRef)
513
1.92M
{
514
1.92M
    nsAutoCString ref;
515
1.92M
    nsresult rv = NS_EscapeURL(aRef, esc_OnlyNonASCII | esc_Spaces, ref, fallible);
516
1.92M
    if (NS_FAILED(rv)) {
517
0
        return rv;
518
0
    }
519
1.92M
520
1.92M
    if (ref.IsEmpty()) {
521
1.91M
        // Empty string means to remove ref completely.
522
1.91M
        mIsRefValid = false;
523
1.91M
        mRef.Truncate(); // invariant: mRef should be empty when it's not valid
524
1.91M
        return NS_OK;
525
1.91M
    }
526
2.24k
527
2.24k
    mIsRefValid = true;
528
2.24k
529
2.24k
    // Gracefully skip initial hash
530
2.24k
    if (ref[0] == '#') {
531
2.24k
        mRef = Substring(ref, 1);
532
2.24k
    } else {
533
0
        mRef = ref;
534
0
    }
535
2.24k
536
2.24k
    return NS_OK;
537
2.24k
}
538
539
NS_IMETHODIMP
540
nsSimpleURI::Equals(nsIURI* other, bool *result)
541
0
{
542
0
    return EqualsInternal(other, eHonorRef, result);
543
0
}
544
545
NS_IMETHODIMP
546
nsSimpleURI::EqualsExceptRef(nsIURI* other, bool *result)
547
0
{
548
0
    return EqualsInternal(other, eIgnoreRef, result);
549
0
}
550
551
/* virtual */ nsresult
552
nsSimpleURI::EqualsInternal(nsIURI* other,
553
                            nsSimpleURI::RefHandlingEnum refHandlingMode,
554
                            bool* result)
555
0
{
556
0
    NS_ENSURE_ARG_POINTER(other);
557
0
    MOZ_ASSERT(result, "null pointer");
558
0
559
0
    RefPtr<nsSimpleURI> otherUri;
560
0
    nsresult rv = other->QueryInterface(kThisSimpleURIImplementationCID,
561
0
                                        getter_AddRefs(otherUri));
562
0
    if (NS_FAILED(rv)) {
563
0
        *result = false;
564
0
        return NS_OK;
565
0
    }
566
0
567
0
    *result = EqualsInternal(otherUri, refHandlingMode);
568
0
    return NS_OK;
569
0
}
570
571
bool
572
nsSimpleURI::EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMode)
573
0
{
574
0
    bool result = (mScheme == otherUri->mScheme &&
575
0
                   mPath   == otherUri->mPath);
576
0
577
0
    if (result) {
578
0
        result = (mIsQueryValid == otherUri->mIsQueryValid &&
579
0
                  (!mIsQueryValid || mQuery == otherUri->mQuery));
580
0
    }
581
0
582
0
    if (result && refHandlingMode == eHonorRef) {
583
0
        result = (mIsRefValid == otherUri->mIsRefValid &&
584
0
                  (!mIsRefValid || mRef == otherUri->mRef));
585
0
    }
586
0
587
0
    return result;
588
0
}
589
590
NS_IMETHODIMP
591
nsSimpleURI::SchemeIs(const char *i_Scheme, bool *o_Equals)
592
0
{
593
0
    NS_ENSURE_ARG_POINTER(o_Equals);
594
0
    if (!i_Scheme) return NS_ERROR_NULL_POINTER;
595
0
596
0
    const char *this_scheme = mScheme.get();
597
0
598
0
    // mScheme is guaranteed to be lower case.
599
0
    if (*i_Scheme == *this_scheme || *i_Scheme == (*this_scheme - ('a' - 'A')) ) {
600
0
        *o_Equals = PL_strcasecmp(this_scheme, i_Scheme) ? false : true;
601
0
    } else {
602
0
        *o_Equals = false;
603
0
    }
604
0
605
0
    return NS_OK;
606
0
}
607
608
/* virtual */ nsSimpleURI*
609
nsSimpleURI::StartClone(nsSimpleURI::RefHandlingEnum refHandlingMode,
610
                        const nsACString& newRef)
611
0
{
612
0
    nsSimpleURI* url = new nsSimpleURI();
613
0
    SetRefOnClone(url, refHandlingMode, newRef);
614
0
    return url;
615
0
}
616
617
/* virtual */ void
618
nsSimpleURI::SetRefOnClone(nsSimpleURI* url,
619
                           nsSimpleURI::RefHandlingEnum refHandlingMode,
620
                           const nsACString& newRef)
621
0
{
622
0
    if (refHandlingMode == eHonorRef) {
623
0
        url->mRef = mRef;
624
0
        url->mIsRefValid = mIsRefValid;
625
0
    } else if (refHandlingMode == eReplaceRef) {
626
0
        url->SetRef(newRef);
627
0
    }
628
0
}
629
630
nsresult
631
nsSimpleURI::Clone(nsIURI** result)
632
0
{
633
0
    return CloneInternal(eHonorRef, EmptyCString(), result);
634
0
}
635
636
nsresult
637
nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
638
                           const nsACString &newRef,
639
                           nsIURI** result)
640
0
{
641
0
    RefPtr<nsSimpleURI> url = StartClone(refHandlingMode, newRef);
642
0
    if (!url)
643
0
        return NS_ERROR_OUT_OF_MEMORY;
644
0
645
0
    url->mScheme = mScheme;
646
0
    url->mPath = mPath;
647
0
648
0
    url->mIsQueryValid = mIsQueryValid;
649
0
    if (url->mIsQueryValid) {
650
0
      url->mQuery = mQuery;
651
0
    }
652
0
653
0
    url.forget(result);
654
0
    return NS_OK;
655
0
}
656
657
NS_IMETHODIMP
658
nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
659
0
{
660
0
    result = relativePath;
661
0
    return NS_OK;
662
0
}
663
664
NS_IMETHODIMP
665
nsSimpleURI::GetAsciiSpec(nsACString &aResult)
666
0
{
667
0
    nsresult rv = GetSpec(aResult);
668
0
    if (NS_FAILED(rv)) return rv;
669
0
    MOZ_ASSERT(IsASCII(aResult), "The spec should be ASCII");
670
0
    return NS_OK;
671
0
}
672
673
NS_IMETHODIMP
674
nsSimpleURI::GetAsciiHostPort(nsACString &result)
675
0
{
676
0
    // XXX This behavior mimics GetHostPort.
677
0
    return NS_ERROR_FAILURE;
678
0
}
679
680
NS_IMETHODIMP
681
nsSimpleURI::GetAsciiHost(nsACString &result)
682
0
{
683
0
    result.Truncate();
684
0
    return NS_OK;
685
0
}
686
687
//----------------------------------------------------------------------------
688
// nsSimpleURI::nsIClassInfo
689
//----------------------------------------------------------------------------
690
691
NS_IMETHODIMP
692
nsSimpleURI::GetInterfaces(uint32_t *count, nsIID * **array)
693
1.62M
{
694
1.62M
    *count = 0;
695
1.62M
    *array = nullptr;
696
1.62M
    return NS_OK;
697
1.62M
}
698
699
NS_IMETHODIMP
700
nsSimpleURI::GetScriptableHelper(nsIXPCScriptable **_retval)
701
1.62M
{
702
1.62M
    *_retval = nullptr;
703
1.62M
    return NS_OK;
704
1.62M
}
705
706
NS_IMETHODIMP
707
nsSimpleURI::GetContractID(nsACString& aContractID)
708
0
{
709
0
    // Make sure to modify any subclasses as needed if this ever
710
0
    // changes.
711
0
    aContractID.SetIsVoid(true);
712
0
    return NS_OK;
713
0
}
714
715
NS_IMETHODIMP
716
nsSimpleURI::GetClassDescription(nsACString& aClassDescription)
717
0
{
718
0
    aClassDescription.SetIsVoid(true);
719
0
    return NS_OK;
720
0
}
721
722
NS_IMETHODIMP
723
nsSimpleURI::GetClassID(nsCID * *aClassID)
724
0
{
725
0
    // Make sure to modify any subclasses as needed if this ever
726
0
    // changes to not call the virtual GetClassIDNoAlloc.
727
0
    *aClassID = (nsCID*) moz_xmalloc(sizeof(nsCID));
728
0
    return GetClassIDNoAlloc(*aClassID);
729
0
}
730
731
NS_IMETHODIMP
732
nsSimpleURI::GetFlags(uint32_t *aFlags)
733
0
{
734
0
    *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
735
0
    return NS_OK;
736
0
}
737
738
NS_IMETHODIMP
739
nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
740
0
{
741
0
    *aClassIDNoAlloc = kSimpleURICID;
742
0
    return NS_OK;
743
0
}
744
745
//----------------------------------------------------------------------------
746
// nsSimpleURI::nsISizeOf
747
//----------------------------------------------------------------------------
748
749
size_t
750
nsSimpleURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
751
0
{
752
0
  return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
753
0
         mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
754
0
         mQuery.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
755
0
         mRef.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
756
0
}
757
758
size_t
759
0
nsSimpleURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
760
0
  return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
761
0
}
762
763
NS_IMETHODIMP
764
nsSimpleURI::GetFilePath(nsACString& aFilePath)
765
0
{
766
0
    aFilePath = mPath;
767
0
    return NS_OK;
768
0
}
769
770
nsresult
771
nsSimpleURI::SetFilePath(const nsACString& aFilePath)
772
0
{
773
0
    return NS_ERROR_FAILURE;
774
0
}
775
776
NS_IMETHODIMP
777
nsSimpleURI::GetQuery(nsACString& aQuery)
778
0
{
779
0
    if (!mIsQueryValid) {
780
0
        MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
781
0
        aQuery.Truncate();
782
0
    } else {
783
0
        aQuery = mQuery;
784
0
    }
785
0
    return NS_OK;
786
0
}
787
788
nsresult
789
nsSimpleURI::SetQuery(const nsACString& aQuery)
790
1.92M
{
791
1.92M
    nsAutoCString query;
792
1.92M
    nsresult rv = NS_EscapeURL(aQuery, esc_OnlyNonASCII, query, fallible);
793
1.92M
    if (NS_FAILED(rv)) {
794
0
        return rv;
795
0
    }
796
1.92M
797
1.92M
    if (query.IsEmpty()) {
798
1.91M
        // Empty string means to remove query completely.
799
1.91M
        mIsQueryValid = false;
800
1.91M
        mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
801
1.91M
        return NS_OK;
802
1.91M
    }
803
2.18k
804
2.18k
    mIsQueryValid = true;
805
2.18k
806
2.18k
    // Gracefully skip initial question mark
807
2.18k
    if (query[0] == '?') {
808
2.18k
        mQuery = Substring(query, 1);
809
2.18k
    } else {
810
0
        mQuery = query;
811
0
    }
812
2.18k
813
2.18k
    return NS_OK;
814
2.18k
}
815
816
nsresult
817
nsSimpleURI::SetQueryWithEncoding(const nsACString& aQuery,
818
                                  const Encoding* aEncoding)
819
0
{
820
0
    return SetQuery(aQuery);
821
0
}
822
823
// Queries this list of interfaces. If none match, it queries mURI.
824
NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleURI::Mutator,
825
                                nsIURISetters,
826
                                nsIURIMutator,
827
                                nsISerializable)
828
829
NS_IMETHODIMP
830
nsSimpleURI::Mutate(nsIURIMutator** aMutator)
831
0
{
832
0
    RefPtr<nsSimpleURI::Mutator> mutator = new nsSimpleURI::Mutator();
833
0
    nsresult rv = mutator->InitFromURI(this);
834
0
    if (NS_FAILED(rv)) {
835
0
        return rv;
836
0
    }
837
0
    mutator.forget(aMutator);
838
0
    return NS_OK;
839
0
}
840
841
} // namespace net
842
} // namespace mozilla