/src/mozilla-central/netwerk/protocol/about/nsAboutProtocolHandler.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 "base/basictypes.h" |
7 | | #include "mozilla/ArrayUtils.h" |
8 | | |
9 | | #include "nsAboutProtocolHandler.h" |
10 | | #include "nsIURI.h" |
11 | | #include "nsIAboutModule.h" |
12 | | #include "nsString.h" |
13 | | #include "nsNetCID.h" |
14 | | #include "nsAboutProtocolUtils.h" |
15 | | #include "nsError.h" |
16 | | #include "nsNetUtil.h" |
17 | | #include "nsIObjectInputStream.h" |
18 | | #include "nsIObjectOutputStream.h" |
19 | | #include "nsAutoPtr.h" |
20 | | #include "nsIWritablePropertyBag2.h" |
21 | | #include "nsIChannel.h" |
22 | | #include "nsIScriptError.h" |
23 | | #include "nsIEnterprisePolicies.h" |
24 | | |
25 | | namespace mozilla { |
26 | | namespace net { |
27 | | |
28 | | static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); |
29 | | static NS_DEFINE_CID(kNestedAboutURICID, NS_NESTEDABOUTURI_CID); |
30 | | |
31 | 0 | static bool IsSafeForUntrustedContent(nsIAboutModule *aModule, nsIURI *aURI) { |
32 | 0 | uint32_t flags; |
33 | 0 | nsresult rv = aModule->GetURIFlags(aURI, &flags); |
34 | 0 | NS_ENSURE_SUCCESS(rv, false); |
35 | 0 |
|
36 | 0 | return (flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) != 0; |
37 | 0 | } |
38 | | |
39 | 856 | static bool IsSafeToLinkForUntrustedContent(nsIAboutModule *aModule, nsIURI *aURI) { |
40 | 856 | uint32_t flags; |
41 | 856 | nsresult rv = aModule->GetURIFlags(aURI, &flags); |
42 | 856 | NS_ENSURE_SUCCESS(rv, false); |
43 | 856 | |
44 | 856 | return (flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) && (flags & nsIAboutModule::MAKE_LINKABLE); |
45 | 856 | } |
46 | | //////////////////////////////////////////////////////////////////////////////// |
47 | | |
48 | | NS_IMPL_ISUPPORTS(nsAboutProtocolHandler, nsIProtocolHandler, |
49 | | nsIProtocolHandlerWithDynamicFlags, nsISupportsWeakReference) |
50 | | |
51 | | //////////////////////////////////////////////////////////////////////////////// |
52 | | // nsIProtocolHandler methods: |
53 | | |
54 | | NS_IMETHODIMP |
55 | | nsAboutProtocolHandler::GetScheme(nsACString &result) |
56 | 0 | { |
57 | 0 | result.AssignLiteral("about"); |
58 | 0 | return NS_OK; |
59 | 0 | } |
60 | | |
61 | | NS_IMETHODIMP |
62 | | nsAboutProtocolHandler::GetDefaultPort(int32_t *result) |
63 | 0 | { |
64 | 0 | *result = -1; // no port for about: URLs |
65 | 0 | return NS_OK; |
66 | 0 | } |
67 | | |
68 | | NS_IMETHODIMP |
69 | | nsAboutProtocolHandler::GetProtocolFlags(uint32_t *result) |
70 | 0 | { |
71 | 0 | *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD | URI_SCHEME_NOT_SELF_LINKABLE; |
72 | 0 | return NS_OK; |
73 | 0 | } |
74 | | |
75 | | NS_IMETHODIMP |
76 | | nsAboutProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags) |
77 | 0 | { |
78 | 0 | // First use the default (which is "unsafe for content"): |
79 | 0 | GetProtocolFlags(aFlags); |
80 | 0 |
|
81 | 0 | // Now try to see if this URI overrides the default: |
82 | 0 | nsCOMPtr<nsIAboutModule> aboutMod; |
83 | 0 | nsresult rv = NS_GetAboutModule(aURI, getter_AddRefs(aboutMod)); |
84 | 0 | if (NS_FAILED(rv)) { |
85 | 0 | // Swallow this and just tell the consumer the default: |
86 | 0 | return NS_OK; |
87 | 0 | } |
88 | 0 | uint32_t aboutModuleFlags = 0; |
89 | 0 | rv = aboutMod->GetURIFlags(aURI, &aboutModuleFlags); |
90 | 0 | // This should never happen, so pass back the error: |
91 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
92 | 0 |
|
93 | 0 | // Secure (https) pages can load safe about pages without becoming |
94 | 0 | // mixed content. |
95 | 0 | if (aboutModuleFlags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) { |
96 | 0 | *aFlags |= URI_IS_POTENTIALLY_TRUSTWORTHY; |
97 | 0 | // about: pages can only be loaded by unprivileged principals |
98 | 0 | // if they are marked as LINKABLE |
99 | 0 | if (aboutModuleFlags & nsIAboutModule::MAKE_LINKABLE) { |
100 | 0 | // Replace URI_DANGEROUS_TO_LOAD with URI_LOADABLE_BY_ANYONE. |
101 | 0 | *aFlags &= ~URI_DANGEROUS_TO_LOAD; |
102 | 0 | *aFlags |= URI_LOADABLE_BY_ANYONE; |
103 | 0 | } |
104 | 0 | } |
105 | 0 | return NS_OK; |
106 | 0 | } |
107 | | |
108 | | NS_IMETHODIMP |
109 | | nsAboutProtocolHandler::NewURI(const nsACString &aSpec, |
110 | | const char *aCharset, // ignore charset info |
111 | | nsIURI *aBaseURI, |
112 | | nsIURI **result) |
113 | 4.09k | { |
114 | 4.09k | *result = nullptr; |
115 | 4.09k | nsresult rv; |
116 | 4.09k | |
117 | 4.09k | |
118 | 4.09k | // Use a simple URI to parse out some stuff first |
119 | 4.09k | nsCOMPtr<nsIURI> url; |
120 | 4.09k | rv = NS_MutateURI(new nsSimpleURI::Mutator()) |
121 | 4.09k | .SetSpec(aSpec) |
122 | 4.09k | .Finalize(url); |
123 | 4.09k | |
124 | 4.09k | if (NS_FAILED(rv)) { |
125 | 0 | return rv; |
126 | 0 | } |
127 | 4.09k | |
128 | 4.09k | // Unfortunately, people create random about: URIs that don't correspond to |
129 | 4.09k | // about: modules... Since those URIs will never open a channel, might as |
130 | 4.09k | // well consider them unsafe for better perf, and just in case. |
131 | 4.09k | bool isSafe = false; |
132 | 4.09k | |
133 | 4.09k | nsCOMPtr<nsIAboutModule> aboutMod; |
134 | 4.09k | rv = NS_GetAboutModule(url, getter_AddRefs(aboutMod)); |
135 | 4.09k | if (NS_SUCCEEDED(rv)) { |
136 | 856 | isSafe = IsSafeToLinkForUntrustedContent(aboutMod, url); |
137 | 856 | } |
138 | 4.09k | |
139 | 4.09k | if (isSafe) { |
140 | 0 | // We need to indicate that this baby is safe. Use an inner URI that |
141 | 0 | // no one but the security manager will see. Make sure to preserve our |
142 | 0 | // path, in case someone decides to hardcode checks for particular |
143 | 0 | // about: URIs somewhere. |
144 | 0 | nsAutoCString spec; |
145 | 0 | rv = url->GetPathQueryRef(spec); |
146 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
147 | 0 |
|
148 | 0 | spec.InsertLiteral("moz-safe-about:", 0); |
149 | 0 |
|
150 | 0 | nsCOMPtr<nsIURI> inner; |
151 | 0 | rv = NS_NewURI(getter_AddRefs(inner), spec); |
152 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
153 | 0 |
|
154 | 0 | nsCOMPtr<nsIURI> base(aBaseURI); |
155 | 0 | rv = NS_MutateURI(new nsNestedAboutURI::Mutator()) |
156 | 0 | .Apply(NS_MutatorMethod(&nsINestedAboutURIMutator::InitWithBase, |
157 | 0 | inner, base)) |
158 | 0 | .SetSpec(aSpec) |
159 | 0 | .Finalize(url); |
160 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
161 | 0 | } |
162 | 4.09k | |
163 | 4.09k | url.swap(*result); |
164 | 4.09k | return NS_OK; |
165 | 4.09k | } |
166 | | |
167 | | NS_IMETHODIMP |
168 | | nsAboutProtocolHandler::NewChannel2(nsIURI* uri, |
169 | | nsILoadInfo* aLoadInfo, |
170 | | nsIChannel** result) |
171 | 0 | { |
172 | 0 | NS_ENSURE_ARG_POINTER(uri); |
173 | 0 |
|
174 | 0 | // about:what you ask? |
175 | 0 | nsCOMPtr<nsIAboutModule> aboutMod; |
176 | 0 | nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod)); |
177 | 0 |
|
178 | 0 | bool aboutPageAllowed = true; |
179 | 0 | nsAutoCString path; |
180 | 0 | nsresult rv2 = NS_GetAboutModuleName(uri, path); |
181 | 0 | if (NS_SUCCEEDED(rv2)) { |
182 | 0 | if (path.EqualsLiteral("srcdoc")) { |
183 | 0 | // about:srcdoc is meant to be unresolvable, yet is included in the |
184 | 0 | // about lookup tables so that it can pass security checks when used in |
185 | 0 | // a srcdoc iframe. To ensure that it stays unresolvable, we pretend |
186 | 0 | // that it doesn't exist. |
187 | 0 | rv = NS_ERROR_FACTORY_NOT_REGISTERED; |
188 | 0 | } else if (!path.EqualsLiteral("blank") && |
189 | 0 | !path.EqualsLiteral("neterror") && |
190 | 0 | !path.EqualsLiteral("home") && |
191 | 0 | !path.EqualsLiteral("welcome") && |
192 | 0 | !path.EqualsLiteral("newtab") && |
193 | 0 | !path.EqualsLiteral("certerror")) { |
194 | 0 | nsCOMPtr<nsIEnterprisePolicies> policyManager = |
195 | 0 | do_GetService("@mozilla.org/browser/enterprisepolicies;1", &rv2); |
196 | 0 | if (NS_SUCCEEDED(rv2)) { |
197 | 0 | nsAutoCString normalizedURL; |
198 | 0 | normalizedURL.AssignLiteral("about:"); |
199 | 0 | normalizedURL.Append(path); |
200 | 0 | rv2 = policyManager->IsAllowed(normalizedURL, &aboutPageAllowed); |
201 | 0 | if (NS_FAILED(rv2)) { |
202 | 0 | aboutPageAllowed = false; |
203 | 0 | } |
204 | 0 | } |
205 | 0 | } |
206 | 0 | } |
207 | 0 |
|
208 | 0 | if (NS_SUCCEEDED(rv)) { |
209 | 0 | // The standard return case: |
210 | 0 | rv = aboutMod->NewChannel(uri, aLoadInfo, result); |
211 | 0 | if (NS_SUCCEEDED(rv)) { |
212 | 0 | // Not all implementations of nsIAboutModule::NewChannel() |
213 | 0 | // set the LoadInfo on the newly created channel yet, as |
214 | 0 | // an interim solution we set the LoadInfo here if not |
215 | 0 | // available on the channel. Bug 1087720 |
216 | 0 | nsCOMPtr<nsILoadInfo> loadInfo = (*result)->GetLoadInfo(); |
217 | 0 | if (aLoadInfo != loadInfo) { |
218 | 0 | if (loadInfo) { |
219 | 0 | NS_ASSERTION(false, |
220 | 0 | "nsIAboutModule->newChannel(aURI, aLoadInfo) needs to set LoadInfo"); |
221 | 0 | const char16_t* params[] = { |
222 | 0 | u"nsIAboutModule->newChannel(aURI)", |
223 | 0 | u"nsIAboutModule->newChannel(aURI, aLoadInfo)" |
224 | 0 | }; |
225 | 0 | nsContentUtils::ReportToConsole( |
226 | 0 | nsIScriptError::warningFlag, |
227 | 0 | NS_LITERAL_CSTRING("Security by Default"), |
228 | 0 | nullptr, // aDocument |
229 | 0 | nsContentUtils::eNECKO_PROPERTIES, |
230 | 0 | "APIDeprecationWarning", |
231 | 0 | params, mozilla::ArrayLength(params)); |
232 | 0 | } |
233 | 0 | (*result)->SetLoadInfo(aLoadInfo); |
234 | 0 | } |
235 | 0 |
|
236 | 0 | // If this URI is safe for untrusted content, enforce that its |
237 | 0 | // principal be based on the channel's originalURI by setting the |
238 | 0 | // owner to null. |
239 | 0 | // Note: this relies on aboutMod's newChannel implementation |
240 | 0 | // having set the proper originalURI, which probably isn't ideal. |
241 | 0 | if (IsSafeForUntrustedContent(aboutMod, uri)) { |
242 | 0 | (*result)->SetOwner(nullptr); |
243 | 0 | } |
244 | 0 |
|
245 | 0 | RefPtr<nsNestedAboutURI> aboutURI; |
246 | 0 | nsresult rv2 = uri->QueryInterface(kNestedAboutURICID, |
247 | 0 | getter_AddRefs(aboutURI)); |
248 | 0 | if (NS_SUCCEEDED(rv2) && aboutURI->GetBaseURI()) { |
249 | 0 | nsCOMPtr<nsIWritablePropertyBag2> writableBag = |
250 | 0 | do_QueryInterface(*result); |
251 | 0 | if (writableBag) { |
252 | 0 | writableBag-> |
253 | 0 | SetPropertyAsInterface(NS_LITERAL_STRING("baseURI"), |
254 | 0 | aboutURI->GetBaseURI()); |
255 | 0 | } |
256 | 0 | } |
257 | 0 | if (!aboutPageAllowed) { |
258 | 0 | (*result)->Cancel(NS_ERROR_BLOCKED_BY_POLICY); |
259 | 0 | } |
260 | 0 | } |
261 | 0 | return rv; |
262 | 0 | } |
263 | 0 |
|
264 | 0 | // mumble... |
265 | 0 |
|
266 | 0 | if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) { |
267 | 0 | // This looks like an about: we don't know about. Convert |
268 | 0 | // this to an invalid URI error. |
269 | 0 | rv = NS_ERROR_MALFORMED_URI; |
270 | 0 | } |
271 | 0 |
|
272 | 0 | return rv; |
273 | 0 | } |
274 | | |
275 | | NS_IMETHODIMP |
276 | | nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) |
277 | 0 | { |
278 | 0 | return NewChannel2(uri, nullptr, result); |
279 | 0 | } |
280 | | |
281 | | NS_IMETHODIMP |
282 | | nsAboutProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) |
283 | 0 | { |
284 | 0 | // don't override anything. |
285 | 0 | *_retval = false; |
286 | 0 | return NS_OK; |
287 | 0 | } |
288 | | |
289 | | //////////////////////////////////////////////////////////////////////////////// |
290 | | // Safe about protocol handler impl |
291 | | |
292 | | NS_IMPL_ISUPPORTS(nsSafeAboutProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference) |
293 | | |
294 | | // nsIProtocolHandler methods: |
295 | | |
296 | | NS_IMETHODIMP |
297 | | nsSafeAboutProtocolHandler::GetScheme(nsACString &result) |
298 | 0 | { |
299 | 0 | result.AssignLiteral("moz-safe-about"); |
300 | 0 | return NS_OK; |
301 | 0 | } |
302 | | |
303 | | NS_IMETHODIMP |
304 | | nsSafeAboutProtocolHandler::GetDefaultPort(int32_t *result) |
305 | 0 | { |
306 | 0 | *result = -1; // no port for moz-safe-about: URLs |
307 | 0 | return NS_OK; |
308 | 0 | } |
309 | | |
310 | | NS_IMETHODIMP |
311 | | nsSafeAboutProtocolHandler::GetProtocolFlags(uint32_t *result) |
312 | 0 | { |
313 | 0 | *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE | URI_IS_POTENTIALLY_TRUSTWORTHY; |
314 | 0 | return NS_OK; |
315 | 0 | } |
316 | | |
317 | | NS_IMETHODIMP |
318 | | nsSafeAboutProtocolHandler::NewURI(const nsACString &aSpec, |
319 | | const char *aCharset, // ignore charset info |
320 | | nsIURI *aBaseURI, |
321 | | nsIURI **result) |
322 | 0 | { |
323 | 0 | nsresult rv = NS_MutateURI(new nsSimpleURI::Mutator()) |
324 | 0 | .SetSpec(aSpec) |
325 | 0 | .Finalize(result); |
326 | 0 | if (NS_FAILED(rv)) { |
327 | 0 | return rv; |
328 | 0 | } |
329 | 0 | |
330 | 0 | return NS_OK; |
331 | 0 | } |
332 | | |
333 | | NS_IMETHODIMP |
334 | | nsSafeAboutProtocolHandler::NewChannel2(nsIURI* uri, |
335 | | nsILoadInfo* aLoadInfo, |
336 | | nsIChannel** result) |
337 | 0 | { |
338 | 0 | *result = nullptr; |
339 | 0 | return NS_ERROR_NOT_AVAILABLE; |
340 | 0 | } |
341 | | |
342 | | NS_IMETHODIMP |
343 | | nsSafeAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) |
344 | 0 | { |
345 | 0 | *result = nullptr; |
346 | 0 | return NS_ERROR_NOT_AVAILABLE; |
347 | 0 | } |
348 | | |
349 | | NS_IMETHODIMP |
350 | | nsSafeAboutProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) |
351 | 0 | { |
352 | 0 | // don't override anything. |
353 | 0 | *_retval = false; |
354 | 0 | return NS_OK; |
355 | 0 | } |
356 | | |
357 | | //////////////////////////////////////////////////////////// |
358 | | // nsNestedAboutURI implementation |
359 | 0 | NS_INTERFACE_MAP_BEGIN(nsNestedAboutURI) |
360 | 0 | if (aIID.Equals(kNestedAboutURICID)) |
361 | 0 | foundInterface = static_cast<nsIURI*>(this); |
362 | 0 | else |
363 | 0 | NS_INTERFACE_MAP_END_INHERITING(nsSimpleNestedURI) |
364 | | |
365 | | // nsISerializable |
366 | | |
367 | | NS_IMETHODIMP |
368 | | nsNestedAboutURI::Read(nsIObjectInputStream *aStream) |
369 | 0 | { |
370 | 0 | MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead"); |
371 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
372 | 0 | } |
373 | | |
374 | | nsresult |
375 | | nsNestedAboutURI::ReadPrivate(nsIObjectInputStream *aStream) |
376 | 0 | { |
377 | 0 | nsresult rv = nsSimpleNestedURI::ReadPrivate(aStream); |
378 | 0 | if (NS_FAILED(rv)) return rv; |
379 | 0 | |
380 | 0 | bool haveBase; |
381 | 0 | rv = aStream->ReadBoolean(&haveBase); |
382 | 0 | if (NS_FAILED(rv)) return rv; |
383 | 0 | |
384 | 0 | if (haveBase) { |
385 | 0 | nsCOMPtr<nsISupports> supports; |
386 | 0 | rv = aStream->ReadObject(true, getter_AddRefs(supports)); |
387 | 0 | if (NS_FAILED(rv)) return rv; |
388 | 0 | |
389 | 0 | mBaseURI = do_QueryInterface(supports, &rv); |
390 | 0 | if (NS_FAILED(rv)) return rv; |
391 | 0 | } |
392 | 0 | |
393 | 0 | return NS_OK; |
394 | 0 | } |
395 | | |
396 | | NS_IMETHODIMP |
397 | | nsNestedAboutURI::Write(nsIObjectOutputStream* aStream) |
398 | 0 | { |
399 | 0 | nsresult rv = nsSimpleNestedURI::Write(aStream); |
400 | 0 | if (NS_FAILED(rv)) return rv; |
401 | 0 | |
402 | 0 | rv = aStream->WriteBoolean(mBaseURI != nullptr); |
403 | 0 | if (NS_FAILED(rv)) return rv; |
404 | 0 | |
405 | 0 | if (mBaseURI) { |
406 | 0 | // A previous iteration of this code wrote out mBaseURI as nsISupports |
407 | 0 | // and then read it in as nsIURI, which is non-kosher when mBaseURI |
408 | 0 | // implements more than just a single line of interfaces and the |
409 | 0 | // canonical nsISupports* isn't the one a static_cast<> of mBaseURI |
410 | 0 | // would produce. For backwards compatibility with existing |
411 | 0 | // serializations we continue to write mBaseURI as nsISupports but |
412 | 0 | // switch to reading it as nsISupports, with a post-read QI to get to |
413 | 0 | // nsIURI. |
414 | 0 | rv = aStream->WriteCompoundObject(mBaseURI, NS_GET_IID(nsISupports), |
415 | 0 | true); |
416 | 0 | if (NS_FAILED(rv)) return rv; |
417 | 0 | } |
418 | 0 | |
419 | 0 | return NS_OK; |
420 | 0 | } |
421 | | |
422 | | // nsSimpleURI |
423 | | /* virtual */ nsSimpleURI* |
424 | | nsNestedAboutURI::StartClone(nsSimpleURI::RefHandlingEnum aRefHandlingMode, |
425 | | const nsACString& aNewRef) |
426 | 0 | { |
427 | 0 | // Sadly, we can't make use of nsSimpleNestedURI::StartClone here. |
428 | 0 | // However, this function is expected to exactly match that function, |
429 | 0 | // aside from the "new ns***URI()" call. |
430 | 0 | NS_ENSURE_TRUE(mInnerURI, nullptr); |
431 | 0 |
|
432 | 0 | nsCOMPtr<nsIURI> innerClone; |
433 | 0 | nsresult rv = NS_OK; |
434 | 0 | if (aRefHandlingMode == eHonorRef) { |
435 | 0 | innerClone = mInnerURI; |
436 | 0 | } else if (aRefHandlingMode == eReplaceRef) { |
437 | 0 | rv = NS_GetURIWithNewRef(mInnerURI, aNewRef, getter_AddRefs(innerClone)); |
438 | 0 | } else { |
439 | 0 | rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone)); |
440 | 0 | } |
441 | 0 |
|
442 | 0 | if (NS_FAILED(rv)) { |
443 | 0 | return nullptr; |
444 | 0 | } |
445 | 0 | |
446 | 0 | nsNestedAboutURI* url = new nsNestedAboutURI(innerClone, mBaseURI); |
447 | 0 | SetRefOnClone(url, aRefHandlingMode, aNewRef); |
448 | 0 |
|
449 | 0 | return url; |
450 | 0 | } |
451 | | |
452 | | // Queries this list of interfaces. If none match, it queries mURI. |
453 | | NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsNestedAboutURI::Mutator, |
454 | | nsIURISetters, |
455 | | nsIURIMutator, |
456 | | nsISerializable, |
457 | | nsINestedAboutURIMutator) |
458 | | |
459 | | NS_IMETHODIMP |
460 | | nsNestedAboutURI::Mutate(nsIURIMutator** aMutator) |
461 | 0 | { |
462 | 0 | RefPtr<nsNestedAboutURI::Mutator> mutator = new nsNestedAboutURI::Mutator(); |
463 | 0 | nsresult rv = mutator->InitFromURI(this); |
464 | 0 | if (NS_FAILED(rv)) { |
465 | 0 | return rv; |
466 | 0 | } |
467 | 0 | mutator.forget(aMutator); |
468 | 0 | return NS_OK; |
469 | 0 | } |
470 | | |
471 | | // nsIClassInfo |
472 | | NS_IMETHODIMP |
473 | | nsNestedAboutURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) |
474 | 0 | { |
475 | 0 | *aClassIDNoAlloc = kNestedAboutURICID; |
476 | 0 | return NS_OK; |
477 | 0 | } |
478 | | |
479 | | } // namespace net |
480 | | } // namespace mozilla |