Bug 1804798 - Explicitly set auto page name (and corresponding debug flag) when inser...
[gecko.git] / netwerk / base / nsSimpleURI.cpp
blob44c3c2f1334fa7413f068f8a40bec38419da456c
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
6 #include "mozilla/DebugOnly.h"
8 #undef LOG
9 #include "ipc/IPCMessageUtils.h"
11 #include "nsSimpleURI.h"
12 #include "nscore.h"
13 #include "nsCRT.h"
14 #include "nsString.h"
15 #include "plstr.h"
16 #include "nsURLHelper.h"
17 #include "nsNetCID.h"
18 #include "nsIObjectInputStream.h"
19 #include "nsIObjectOutputStream.h"
20 #include "nsEscape.h"
21 #include "nsError.h"
22 #include "mozilla/MemoryReporting.h"
23 #include "mozilla/TextUtils.h"
24 #include "mozilla/ipc/URIUtils.h"
25 #include "nsIClassInfoImpl.h"
26 #include "nsIURIMutator.h"
27 #include "mozilla/net/MozURL.h"
29 using namespace mozilla::ipc;
31 namespace mozilla {
32 namespace net {
34 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
35 NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
37 /* static */
38 already_AddRefed<nsSimpleURI> nsSimpleURI::From(nsIURI* aURI) {
39 RefPtr<nsSimpleURI> uri;
40 nsresult rv = aURI->QueryInterface(kThisSimpleURIImplementationCID,
41 getter_AddRefs(uri));
42 if (NS_FAILED(rv)) {
43 return nullptr;
46 return uri.forget();
49 NS_IMPL_CLASSINFO(nsSimpleURI, nullptr, nsIClassInfo::THREADSAFE,
50 NS_SIMPLEURI_CID)
51 // Empty CI getter. We only need nsIClassInfo for Serialization
52 NS_IMPL_CI_INTERFACE_GETTER0(nsSimpleURI)
54 ////////////////////////////////////////////////////////////////////////////////
55 // nsSimpleURI methods:
57 NS_IMPL_ADDREF(nsSimpleURI)
58 NS_IMPL_RELEASE(nsSimpleURI)
59 NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
60 NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable)
61 NS_INTERFACE_TABLE_TO_MAP_SEGUE
62 NS_IMPL_QUERY_CLASSINFO(nsSimpleURI)
63 if (aIID.Equals(kThisSimpleURIImplementationCID)) {
64 foundInterface = static_cast<nsIURI*>(this);
65 } else
66 NS_INTERFACE_MAP_ENTRY(nsISizeOf)
67 NS_INTERFACE_MAP_END
69 ////////////////////////////////////////////////////////////////////////////////
70 // nsISerializable methods:
72 NS_IMETHODIMP
73 nsSimpleURI::Read(nsIObjectInputStream* aStream) {
74 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
75 return NS_ERROR_NOT_IMPLEMENTED;
78 nsresult nsSimpleURI::ReadPrivate(nsIObjectInputStream* aStream) {
79 nsresult rv;
81 bool isMutable;
82 rv = aStream->ReadBoolean(&isMutable);
83 if (NS_FAILED(rv)) return rv;
84 Unused << isMutable;
86 rv = aStream->ReadCString(mScheme);
87 if (NS_FAILED(rv)) return rv;
89 rv = aStream->ReadCString(mPath);
90 if (NS_FAILED(rv)) return rv;
92 bool isRefValid;
93 rv = aStream->ReadBoolean(&isRefValid);
94 if (NS_FAILED(rv)) return rv;
95 mIsRefValid = isRefValid;
97 if (isRefValid) {
98 rv = aStream->ReadCString(mRef);
99 if (NS_FAILED(rv)) return rv;
100 } else {
101 mRef.Truncate(); // invariant: mRef should be empty when it's not valid
104 bool isQueryValid;
105 rv = aStream->ReadBoolean(&isQueryValid);
106 if (NS_FAILED(rv)) return rv;
107 mIsQueryValid = isQueryValid;
109 if (isQueryValid) {
110 rv = aStream->ReadCString(mQuery);
111 if (NS_FAILED(rv)) return rv;
112 } else {
113 mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
116 return NS_OK;
119 NS_IMETHODIMP
120 nsSimpleURI::Write(nsIObjectOutputStream* aStream) {
121 nsresult rv;
123 rv = aStream->WriteBoolean(false); // former mMutable
124 if (NS_FAILED(rv)) return rv;
126 rv = aStream->WriteStringZ(mScheme.get());
127 if (NS_FAILED(rv)) return rv;
129 rv = aStream->WriteStringZ(mPath.get());
130 if (NS_FAILED(rv)) return rv;
132 rv = aStream->WriteBoolean(mIsRefValid);
133 if (NS_FAILED(rv)) return rv;
135 if (mIsRefValid) {
136 rv = aStream->WriteStringZ(mRef.get());
137 if (NS_FAILED(rv)) return rv;
140 rv = aStream->WriteBoolean(mIsQueryValid);
141 if (NS_FAILED(rv)) return rv;
143 if (mIsQueryValid) {
144 rv = aStream->WriteStringZ(mQuery.get());
145 if (NS_FAILED(rv)) return rv;
148 return NS_OK;
151 void nsSimpleURI::Serialize(URIParams& aParams) {
152 SimpleURIParams params;
154 params.scheme() = mScheme;
155 params.path() = mPath;
157 if (mIsRefValid) {
158 params.ref() = mRef;
159 } else {
160 params.ref().SetIsVoid(true);
163 if (mIsQueryValid) {
164 params.query() = mQuery;
165 } else {
166 params.query().SetIsVoid(true);
169 aParams = params;
172 bool nsSimpleURI::Deserialize(const URIParams& aParams) {
173 if (aParams.type() != URIParams::TSimpleURIParams) {
174 NS_ERROR("Received unknown parameters from the other process!");
175 return false;
178 const SimpleURIParams& params = aParams.get_SimpleURIParams();
180 mScheme = params.scheme();
181 mPath = params.path();
183 if (params.ref().IsVoid()) {
184 mRef.Truncate();
185 mIsRefValid = false;
186 } else {
187 mRef = params.ref();
188 mIsRefValid = true;
191 if (params.query().IsVoid()) {
192 mQuery.Truncate();
193 mIsQueryValid = false;
194 } else {
195 mQuery = params.query();
196 mIsQueryValid = true;
199 return true;
202 ////////////////////////////////////////////////////////////////////////////////
203 // nsIURI methods:
205 NS_IMETHODIMP
206 nsSimpleURI::GetSpec(nsACString& result) {
207 if (!result.Assign(mScheme, fallible) || !result.Append(":"_ns, fallible) ||
208 !result.Append(mPath, fallible)) {
209 return NS_ERROR_OUT_OF_MEMORY;
212 if (mIsQueryValid) {
213 if (!result.Append("?"_ns, fallible) || !result.Append(mQuery, fallible)) {
214 return NS_ERROR_OUT_OF_MEMORY;
216 } else {
217 MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
220 if (mIsRefValid) {
221 if (!result.Append("#"_ns, fallible) || !result.Append(mRef, fallible)) {
222 return NS_ERROR_OUT_OF_MEMORY;
224 } else {
225 MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
228 return NS_OK;
231 // result may contain unescaped UTF-8 characters
232 NS_IMETHODIMP
233 nsSimpleURI::GetSpecIgnoringRef(nsACString& result) {
234 result = mScheme + ":"_ns + mPath;
235 if (mIsQueryValid) {
236 result += "?"_ns + mQuery;
238 return NS_OK;
241 NS_IMETHODIMP
242 nsSimpleURI::GetDisplaySpec(nsACString& aUnicodeSpec) {
243 return GetSpec(aUnicodeSpec);
246 NS_IMETHODIMP
247 nsSimpleURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) {
248 return GetHostPort(aUnicodeHostPort);
251 NS_IMETHODIMP
252 nsSimpleURI::GetDisplayHost(nsACString& aUnicodeHost) {
253 return GetHost(aUnicodeHost);
256 NS_IMETHODIMP
257 nsSimpleURI::GetDisplayPrePath(nsACString& aPrePath) {
258 return GetPrePath(aPrePath);
261 NS_IMETHODIMP
262 nsSimpleURI::GetHasRef(bool* result) {
263 *result = mIsRefValid;
264 return NS_OK;
267 nsresult nsSimpleURI::SetSpecInternal(const nsACString& aSpec,
268 bool aStripWhitespace) {
269 if (StaticPrefs::network_url_max_length() &&
270 aSpec.Length() > StaticPrefs::network_url_max_length()) {
271 return NS_ERROR_MALFORMED_URI;
274 nsresult rv = net_ExtractURLScheme(aSpec, mScheme);
275 if (NS_FAILED(rv)) {
276 return rv;
279 nsAutoCString spec;
280 rv = net_FilterAndEscapeURI(
281 aSpec, esc_OnlyNonASCII,
282 aStripWhitespace ? ASCIIMask::MaskWhitespace() : ASCIIMask::MaskCRLFTab(),
283 spec);
284 if (NS_FAILED(rv)) {
285 return rv;
288 int32_t colonPos = spec.FindChar(':');
289 MOZ_ASSERT(colonPos != kNotFound, "A colon should be in this string");
290 // This sets mPath, mQuery and mRef.
291 return SetPathQueryRefInternal(Substring(spec, colonPos + 1));
294 NS_IMETHODIMP
295 nsSimpleURI::GetScheme(nsACString& result) {
296 result = mScheme;
297 return NS_OK;
300 nsresult nsSimpleURI::SetScheme(const nsACString& scheme) {
301 const nsPromiseFlatCString& flat = PromiseFlatCString(scheme);
302 if (!net_IsValidScheme(flat)) {
303 NS_WARNING("the given url scheme contains invalid characters");
304 return NS_ERROR_MALFORMED_URI;
307 mScheme = scheme;
308 ToLowerCase(mScheme);
309 return NS_OK;
312 NS_IMETHODIMP
313 nsSimpleURI::GetPrePath(nsACString& result) {
314 result = mScheme + ":"_ns;
315 return NS_OK;
318 NS_IMETHODIMP
319 nsSimpleURI::GetUserPass(nsACString& result) { return NS_ERROR_FAILURE; }
321 nsresult nsSimpleURI::SetUserPass(const nsACString& userPass) {
322 return NS_ERROR_FAILURE;
325 NS_IMETHODIMP
326 nsSimpleURI::GetUsername(nsACString& result) { return NS_ERROR_FAILURE; }
328 nsresult nsSimpleURI::SetUsername(const nsACString& userName) {
329 return NS_ERROR_FAILURE;
332 NS_IMETHODIMP
333 nsSimpleURI::GetPassword(nsACString& result) { return NS_ERROR_FAILURE; }
335 nsresult nsSimpleURI::SetPassword(const nsACString& password) {
336 return NS_ERROR_FAILURE;
339 NS_IMETHODIMP
340 nsSimpleURI::GetHostPort(nsACString& result) {
341 // Note: Audit all callers before changing this to return an empty
342 // string -- CAPS and UI code may depend on this throwing.
343 // Note: If this is changed, change GetAsciiHostPort as well.
344 return NS_ERROR_FAILURE;
347 nsresult nsSimpleURI::SetHostPort(const nsACString& result) {
348 return NS_ERROR_FAILURE;
351 NS_IMETHODIMP
352 nsSimpleURI::GetHost(nsACString& result) {
353 // Note: Audit all callers before changing this to return an empty
354 // string -- CAPS and UI code depend on this throwing.
355 return NS_ERROR_FAILURE;
358 nsresult nsSimpleURI::SetHost(const nsACString& host) {
359 return NS_ERROR_FAILURE;
362 NS_IMETHODIMP
363 nsSimpleURI::GetPort(int32_t* result) {
364 // Note: Audit all callers before changing this to return an empty
365 // string -- CAPS and UI code may depend on this throwing.
366 return NS_ERROR_FAILURE;
369 nsresult nsSimpleURI::SetPort(int32_t port) { return NS_ERROR_FAILURE; }
371 NS_IMETHODIMP
372 nsSimpleURI::GetPathQueryRef(nsACString& result) {
373 result = mPath;
374 if (mIsQueryValid) {
375 result += "?"_ns + mQuery;
377 if (mIsRefValid) {
378 result += "#"_ns + mRef;
381 return NS_OK;
384 nsresult nsSimpleURI::SetPathQueryRef(const nsACString& aPath) {
385 if (StaticPrefs::network_url_max_length() &&
386 aPath.Length() > StaticPrefs::network_url_max_length()) {
387 return NS_ERROR_MALFORMED_URI;
390 nsAutoCString path;
391 nsresult rv = NS_EscapeURL(aPath, esc_OnlyNonASCII, path, fallible);
392 if (NS_FAILED(rv)) {
393 return rv;
395 return SetPathQueryRefInternal(path);
398 nsresult nsSimpleURI::SetPathQueryRefInternal(const nsACString& aPath) {
399 nsresult rv;
400 const auto* start = aPath.BeginReading();
401 const auto* end = aPath.EndReading();
403 // Find the first instance of ? or # that marks the end of the path.
404 auto hashOrQueryFilter = [](char c) { return c == '?' || c == '#'; };
405 const auto* pathEnd = std::find_if(start, end, hashOrQueryFilter);
407 mIsQueryValid = false;
408 mQuery.Truncate();
410 mIsRefValid = false;
411 mRef.Truncate();
413 // The path
414 if (!mPath.Assign(Substring(start, pathEnd), fallible)) {
415 return NS_ERROR_OUT_OF_MEMORY;
418 if (pathEnd == end) {
419 return NS_OK;
422 const auto* queryEnd =
423 std::find_if(pathEnd, end, [](char c) { return c == '#'; });
425 rv = SetQuery(Substring(pathEnd, queryEnd));
426 if (NS_FAILED(rv)) {
427 return rv;
430 if (queryEnd == end) {
431 return NS_OK;
434 return SetRef(Substring(queryEnd, end));
437 NS_IMETHODIMP
438 nsSimpleURI::GetRef(nsACString& result) {
439 if (!mIsRefValid) {
440 MOZ_ASSERT(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
441 result.Truncate();
442 } else {
443 result = mRef;
446 return NS_OK;
449 // NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
450 // string (and will result in .spec and .path having a terminal #).
451 nsresult nsSimpleURI::SetRef(const nsACString& aRef) {
452 if (StaticPrefs::network_url_max_length() &&
453 aRef.Length() > StaticPrefs::network_url_max_length()) {
454 return NS_ERROR_MALFORMED_URI;
457 nsAutoCString ref;
458 nsresult rv =
459 NS_EscapeURL(aRef, esc_OnlyNonASCII | esc_Spaces, ref, fallible);
460 if (NS_FAILED(rv)) {
461 return rv;
464 if (ref.IsEmpty()) {
465 // Empty string means to remove ref completely.
466 mIsRefValid = false;
467 mRef.Truncate(); // invariant: mRef should be empty when it's not valid
468 return NS_OK;
471 mIsRefValid = true;
473 // Gracefully skip initial hash
474 if (ref[0] == '#') {
475 mRef = Substring(ref, 1);
476 } else {
477 mRef = ref;
480 return NS_OK;
483 NS_IMETHODIMP
484 nsSimpleURI::Equals(nsIURI* other, bool* result) {
485 return EqualsInternal(other, eHonorRef, result);
488 NS_IMETHODIMP
489 nsSimpleURI::EqualsExceptRef(nsIURI* other, bool* result) {
490 return EqualsInternal(other, eIgnoreRef, result);
493 /* virtual */
494 nsresult nsSimpleURI::EqualsInternal(
495 nsIURI* other, nsSimpleURI::RefHandlingEnum refHandlingMode, bool* result) {
496 NS_ENSURE_ARG_POINTER(other);
497 MOZ_ASSERT(result, "null pointer");
499 RefPtr<nsSimpleURI> otherUri;
500 nsresult rv = other->QueryInterface(kThisSimpleURIImplementationCID,
501 getter_AddRefs(otherUri));
502 if (NS_FAILED(rv)) {
503 *result = false;
504 return NS_OK;
507 *result = EqualsInternal(otherUri, refHandlingMode);
508 return NS_OK;
511 bool nsSimpleURI::EqualsInternal(nsSimpleURI* otherUri,
512 RefHandlingEnum refHandlingMode) {
513 bool result = (mScheme == otherUri->mScheme && mPath == otherUri->mPath);
515 if (result) {
516 result = (mIsQueryValid == otherUri->mIsQueryValid &&
517 (!mIsQueryValid || mQuery == otherUri->mQuery));
520 if (result && refHandlingMode == eHonorRef) {
521 result = (mIsRefValid == otherUri->mIsRefValid &&
522 (!mIsRefValid || mRef == otherUri->mRef));
525 return result;
528 NS_IMETHODIMP
529 nsSimpleURI::SchemeIs(const char* i_Scheme, bool* o_Equals) {
530 MOZ_ASSERT(o_Equals, "null pointer");
531 if (!i_Scheme) {
532 *o_Equals = false;
533 return NS_OK;
536 const char* this_scheme = mScheme.get();
538 // mScheme is guaranteed to be lower case.
539 if (*i_Scheme == *this_scheme || *i_Scheme == (*this_scheme - ('a' - 'A'))) {
540 *o_Equals = nsCRT::strcasecmp(this_scheme, i_Scheme) == 0;
541 } else {
542 *o_Equals = false;
545 return NS_OK;
548 /* virtual */ nsSimpleURI* nsSimpleURI::StartClone(
549 nsSimpleURI::RefHandlingEnum refHandlingMode, const nsACString& newRef) {
550 nsSimpleURI* url = new nsSimpleURI();
551 SetRefOnClone(url, refHandlingMode, newRef);
552 return url;
555 /* virtual */
556 void nsSimpleURI::SetRefOnClone(nsSimpleURI* url,
557 nsSimpleURI::RefHandlingEnum refHandlingMode,
558 const nsACString& newRef) {
559 if (refHandlingMode == eHonorRef) {
560 url->mRef = mRef;
561 url->mIsRefValid = mIsRefValid;
562 } else if (refHandlingMode == eReplaceRef) {
563 url->SetRef(newRef);
567 nsresult nsSimpleURI::Clone(nsIURI** result) {
568 return CloneInternal(eHonorRef, ""_ns, result);
571 nsresult nsSimpleURI::CloneInternal(
572 nsSimpleURI::RefHandlingEnum refHandlingMode, const nsACString& newRef,
573 nsIURI** result) {
574 RefPtr<nsSimpleURI> url = StartClone(refHandlingMode, newRef);
575 if (!url) return NS_ERROR_OUT_OF_MEMORY;
577 url->mScheme = mScheme;
578 url->mPath = mPath;
580 url->mIsQueryValid = mIsQueryValid;
581 if (url->mIsQueryValid) {
582 url->mQuery = mQuery;
585 url.forget(result);
586 return NS_OK;
589 NS_IMETHODIMP
590 nsSimpleURI::Resolve(const nsACString& relativePath, nsACString& result) {
591 nsAutoCString scheme;
592 nsresult rv = net_ExtractURLScheme(relativePath, scheme);
593 if (NS_SUCCEEDED(rv)) {
594 result = relativePath;
595 return NS_OK;
598 nsAutoCString spec;
599 rv = GetAsciiSpec(spec);
600 if (NS_WARN_IF(NS_FAILED(rv))) {
601 // If getting the spec fails for some reason, preserve behaviour and just
602 // return the relative path.
603 result = relativePath;
604 return NS_OK;
607 RefPtr<MozURL> url;
608 rv = MozURL::Init(getter_AddRefs(url), spec);
609 if (NS_WARN_IF(NS_FAILED(rv))) {
610 // If parsing the current url fails, we revert to the previous behaviour
611 // and just return the relative path.
612 result = relativePath;
613 return NS_OK;
616 RefPtr<MozURL> url2;
617 rv = MozURL::Init(getter_AddRefs(url2), relativePath, url);
618 if (NS_WARN_IF(NS_FAILED(rv))) {
619 // If parsing the relative url fails, we revert to the previous behaviour
620 // and just return the relative path.
621 result = relativePath;
622 return NS_OK;
625 result = url2->Spec();
626 return NS_OK;
629 NS_IMETHODIMP
630 nsSimpleURI::GetAsciiSpec(nsACString& aResult) {
631 nsresult rv = GetSpec(aResult);
632 if (NS_FAILED(rv)) return rv;
633 MOZ_ASSERT(IsAscii(aResult), "The spec should be ASCII");
634 return NS_OK;
637 NS_IMETHODIMP
638 nsSimpleURI::GetAsciiHostPort(nsACString& result) {
639 // XXX This behavior mimics GetHostPort.
640 return NS_ERROR_FAILURE;
643 NS_IMETHODIMP
644 nsSimpleURI::GetAsciiHost(nsACString& result) {
645 result.Truncate();
646 return NS_OK;
649 //----------------------------------------------------------------------------
650 // nsSimpleURI::nsISizeOf
651 //----------------------------------------------------------------------------
653 size_t nsSimpleURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
654 return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
655 mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
656 mQuery.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
657 mRef.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
660 size_t nsSimpleURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
661 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
664 NS_IMETHODIMP
665 nsSimpleURI::GetFilePath(nsACString& aFilePath) {
666 aFilePath = mPath;
667 return NS_OK;
670 nsresult nsSimpleURI::SetFilePath(const nsACString& aFilePath) {
671 if (mPath.IsEmpty() || mPath.First() != '/') {
672 // cannot-be-a-base
673 return NS_ERROR_MALFORMED_URI;
675 const char* current = aFilePath.BeginReading();
676 const char* end = aFilePath.EndReading();
678 // Only go up to the first ? or # symbol
679 for (; current < end; ++current) {
680 if (*current == '?' || *current == '#') {
681 break;
684 return SetPathQueryRef(
685 nsDependentCSubstring(aFilePath.BeginReading(), current));
688 NS_IMETHODIMP
689 nsSimpleURI::GetQuery(nsACString& aQuery) {
690 if (!mIsQueryValid) {
691 MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
692 aQuery.Truncate();
693 } else {
694 aQuery = mQuery;
696 return NS_OK;
699 nsresult nsSimpleURI::SetQuery(const nsACString& aQuery) {
700 if (StaticPrefs::network_url_max_length() &&
701 aQuery.Length() > StaticPrefs::network_url_max_length()) {
702 return NS_ERROR_MALFORMED_URI;
704 nsAutoCString query;
705 nsresult rv = NS_EscapeURL(aQuery, esc_OnlyNonASCII, query, fallible);
706 if (NS_FAILED(rv)) {
707 return rv;
710 if (query.IsEmpty()) {
711 // Empty string means to remove query completely.
712 mIsQueryValid = false;
713 mQuery.Truncate(); // invariant: mQuery should be empty when it's not valid
714 return NS_OK;
717 mIsQueryValid = true;
719 // Gracefully skip initial question mark
720 if (query[0] == '?') {
721 mQuery = Substring(query, 1);
722 } else {
723 mQuery = query;
726 return NS_OK;
729 nsresult nsSimpleURI::SetQueryWithEncoding(const nsACString& aQuery,
730 const Encoding* aEncoding) {
731 return SetQuery(aQuery);
734 // Queries this list of interfaces. If none match, it queries mURI.
735 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsSimpleURI::Mutator, nsIURISetters,
736 nsIURIMutator, nsISerializable,
737 nsISimpleURIMutator)
739 NS_IMETHODIMP
740 nsSimpleURI::Mutate(nsIURIMutator** aMutator) {
741 RefPtr<nsSimpleURI::Mutator> mutator = new nsSimpleURI::Mutator();
742 nsresult rv = mutator->InitFromURI(this);
743 if (NS_FAILED(rv)) {
744 return rv;
746 mutator.forget(aMutator);
747 return NS_OK;
750 } // namespace net
751 } // namespace mozilla