Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/docshell/base/nsDefaultURIFixup.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 "nsNetCID.h"
8
#include "nsNetUtil.h"
9
#include "nsIProtocolHandler.h"
10
11
#include "nsIFile.h"
12
#include <algorithm>
13
14
#ifdef MOZ_TOOLKIT_SEARCH
15
#include "nsIBrowserSearchService.h"
16
#endif
17
18
#include "nsIURIFixup.h"
19
#include "nsIURIMutator.h"
20
#include "nsDefaultURIFixup.h"
21
#include "mozilla/Preferences.h"
22
#include "mozilla/dom/ContentChild.h"
23
#include "mozilla/ipc/IPCStreamUtils.h"
24
#include "mozilla/ipc/URIUtils.h"
25
#include "mozilla/TextUtils.h"
26
#include "mozilla/Tokenizer.h"
27
#include "mozilla/Unused.h"
28
#include "nsIObserverService.h"
29
#include "nsXULAppAPI.h"
30
31
// Used to check if external protocol schemes are usable
32
#include "nsCExternalHandlerService.h"
33
#include "nsIExternalProtocolService.h"
34
35
using namespace mozilla;
36
37
/* Implementation file */
38
NS_IMPL_ISUPPORTS(nsDefaultURIFixup, nsIURIFixup)
39
40
static bool sInitializedPrefCaches = false;
41
static bool sFixTypos = true;
42
static bool sDNSFirstForSingleWords = false;
43
static bool sFixupKeywords = true;
44
45
nsDefaultURIFixup::nsDefaultURIFixup()
46
0
{
47
0
}
48
49
nsDefaultURIFixup::~nsDefaultURIFixup()
50
0
{
51
0
}
52
53
NS_IMETHODIMP
54
nsDefaultURIFixup::CreateExposableURI(nsIURI* aURI, nsIURI** aReturn)
55
0
{
56
0
  NS_ENSURE_ARG_POINTER(aURI);
57
0
  NS_ENSURE_ARG_POINTER(aReturn);
58
0
59
0
  bool isWyciwyg = false;
60
0
  aURI->SchemeIs("wyciwyg", &isWyciwyg);
61
0
62
0
  nsAutoCString userPass;
63
0
  aURI->GetUserPass(userPass);
64
0
65
0
  // most of the time we can just AddRef and return
66
0
  if (!isWyciwyg && userPass.IsEmpty()) {
67
0
    *aReturn = aURI;
68
0
    NS_ADDREF(*aReturn);
69
0
    return NS_OK;
70
0
  }
71
0
72
0
  // Rats, we have to massage the URI
73
0
  nsCOMPtr<nsIURI> uri;
74
0
  if (isWyciwyg) {
75
0
    nsresult rv = nsContentUtils::RemoveWyciwygScheme(aURI, getter_AddRefs(uri));
76
0
    NS_ENSURE_SUCCESS(rv, rv);
77
0
  } else {
78
0
    // No need to clone the URI as NS_MutateURI does that for us.
79
0
    uri = aURI;
80
0
  }
81
0
82
0
  // hide user:pass unless overridden by pref
83
0
  if (Preferences::GetBool("browser.fixup.hide_user_pass", true)) {
84
0
    Unused << NS_MutateURI(uri)
85
0
                .SetUserPass(EmptyCString())
86
0
                .Finalize(uri);
87
0
  }
88
0
89
0
  uri.forget(aReturn);
90
0
  return NS_OK;
91
0
}
92
93
NS_IMETHODIMP
94
nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI,
95
                                  uint32_t aFixupFlags,
96
                                  nsIInputStream** aPostData, nsIURI** aURI)
97
0
{
98
0
  nsCOMPtr<nsIURIFixupInfo> fixupInfo;
99
0
  nsresult rv = GetFixupURIInfo(aStringURI, aFixupFlags, aPostData,
100
0
                                getter_AddRefs(fixupInfo));
101
0
  NS_ENSURE_SUCCESS(rv, rv);
102
0
103
0
  fixupInfo->GetPreferredURI(aURI);
104
0
  return rv;
105
0
}
106
107
// Returns true if the URL contains a user:password@ or user@
108
static bool
109
HasUserPassword(const nsACString& aStringURI)
110
0
{
111
0
  mozilla::Tokenizer parser(aStringURI);
112
0
  mozilla::Tokenizer::Token token;
113
0
114
0
  // May start with any of "protocol:", "protocol://",  "//", "://"
115
0
  if (parser.Check(Tokenizer::TOKEN_WORD, token)) { // Skip protocol if any
116
0
  }
117
0
  if (parser.CheckChar(':')) { // Skip colon if found
118
0
  }
119
0
  while (parser.CheckChar('/')) { // Skip all of the following slashes
120
0
  }
121
0
122
0
  while (parser.Next(token)) {
123
0
    if (token.Type() == Tokenizer::TOKEN_CHAR) {
124
0
      if (token.AsChar() == '/') {
125
0
        return false;
126
0
      }
127
0
      if (token.AsChar() == '@') {
128
0
        return true;
129
0
      }
130
0
    }
131
0
  }
132
0
133
0
  return false;
134
0
}
135
136
// Assume that 1 tab is accidental, but more than 1 implies this is
137
// supposed to be tab-separated content.
138
static bool
139
MaybeTabSeparatedContent(const nsCString& aStringURI)
140
0
{
141
0
  auto firstTab = aStringURI.FindChar('\t');
142
0
  return firstTab != kNotFound && aStringURI.RFindChar('\t') != firstTab;
143
0
}
144
145
NS_IMETHODIMP
146
nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
147
                                   uint32_t aFixupFlags,
148
                                   nsIInputStream** aPostData,
149
                                   nsIURIFixupInfo** aInfo)
150
0
{
151
0
  NS_ENSURE_ARG(!aStringURI.IsEmpty());
152
0
153
0
  nsresult rv;
154
0
155
0
  nsAutoCString uriString(aStringURI);
156
0
157
0
  // Eliminate embedded newlines, which single-line text fields now allow:
158
0
  uriString.StripCRLF();
159
0
  // Cleanup the empty spaces and tabs that might be on each end:
160
0
  uriString.Trim(" \t");
161
0
162
0
  NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
163
0
164
0
  RefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(uriString);
165
0
  NS_ADDREF(*aInfo = info);
166
0
167
0
  nsCOMPtr<nsIIOService> ioService =
168
0
    do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
169
0
  NS_ENSURE_SUCCESS(rv, rv);
170
0
  nsAutoCString scheme;
171
0
  ioService->ExtractScheme(aStringURI, scheme);
172
0
173
0
  // View-source is a pseudo scheme. We're interested in fixing up the stuff
174
0
  // after it. The easiest way to do that is to call this method again with the
175
0
  // "view-source:" lopped off and then prepend it again afterwards.
176
0
177
0
  if (scheme.EqualsLiteral("view-source")) {
178
0
    nsCOMPtr<nsIURIFixupInfo> uriInfo;
179
0
    // We disable keyword lookup and alternate URIs so that small typos don't
180
0
    // cause us to look at very different domains
181
0
    uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
182
0
                                         & ~FIXUP_FLAGS_MAKE_ALTERNATE_URI;
183
0
184
0
    const uint32_t viewSourceLen = sizeof("view-source:") - 1;
185
0
    nsAutoCString innerURIString(Substring(uriString, viewSourceLen,
186
0
                                           uriString.Length() -
187
0
                                           viewSourceLen));
188
0
    // Prevent recursion:
189
0
    innerURIString.Trim(" ");
190
0
    nsAutoCString innerScheme;
191
0
    ioService->ExtractScheme(innerURIString, innerScheme);
192
0
    if (innerScheme.EqualsLiteral("view-source")) {
193
0
      return NS_ERROR_FAILURE;
194
0
    }
195
0
196
0
    rv = GetFixupURIInfo(innerURIString, newFixupFlags, aPostData,
197
0
                         getter_AddRefs(uriInfo));
198
0
    if (NS_FAILED(rv)) {
199
0
      return NS_ERROR_FAILURE;
200
0
    }
201
0
    nsAutoCString spec;
202
0
    nsCOMPtr<nsIURI> uri;
203
0
    uriInfo->GetPreferredURI(getter_AddRefs(uri));
204
0
    if (!uri) {
205
0
      return NS_ERROR_FAILURE;
206
0
    }
207
0
    uri->GetSpec(spec);
208
0
    uriString.AssignLiteral("view-source:");
209
0
    uriString.Append(spec);
210
0
  } else {
211
0
    // Check for if it is a file URL
212
0
    nsCOMPtr<nsIURI> uri;
213
0
    FileURIFixup(uriString, getter_AddRefs(uri));
214
0
    // NB: FileURIFixup only returns a URI if it had to fix the protocol to
215
0
    // do so, so passing in file:///foo/bar will not hit this path:
216
0
    if (uri) {
217
0
      uri.swap(info->mFixedURI);
218
0
      info->mPreferredURI = info->mFixedURI;
219
0
      info->mFixupChangedProtocol = true;
220
0
      return NS_OK;
221
0
    }
222
0
  }
223
0
224
0
  if (!sInitializedPrefCaches) {
225
0
    // Check if we want to fix up common scheme typos.
226
0
    rv = Preferences::AddBoolVarCache(&sFixTypos,
227
0
                                      "browser.fixup.typo.scheme",
228
0
                                      sFixTypos);
229
0
    MOZ_ASSERT(NS_SUCCEEDED(rv),
230
0
               "Failed to observe \"browser.fixup.typo.scheme\"");
231
0
232
0
    rv = Preferences::AddBoolVarCache(&sDNSFirstForSingleWords,
233
0
                                      "browser.fixup.dns_first_for_single_words",
234
0
                                      sDNSFirstForSingleWords);
235
0
    MOZ_ASSERT(NS_SUCCEEDED(rv),
236
0
               "Failed to observe \"browser.fixup.dns_first_for_single_words\"");
237
0
238
0
    rv = Preferences::AddBoolVarCache(&sFixupKeywords, "keyword.enabled",
239
0
                                      sFixupKeywords);
240
0
    MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to observe \"keyword.enabled\"");
241
0
    sInitializedPrefCaches = true;
242
0
  }
243
0
244
0
  // Fix up common scheme typos.
245
0
  if (sFixTypos && (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) {
246
0
    // Fast-path for common cases.
247
0
    if (scheme.IsEmpty() ||
248
0
        scheme.EqualsLiteral("http") ||
249
0
        scheme.EqualsLiteral("https") ||
250
0
        scheme.EqualsLiteral("ftp") ||
251
0
        scheme.EqualsLiteral("file")) {
252
0
      // Do nothing.
253
0
    } else if (scheme.EqualsLiteral("ttp")) {
254
0
      // ttp -> http.
255
0
      uriString.ReplaceLiteral(0, 3, "http");
256
0
      scheme.AssignLiteral("http");
257
0
      info->mFixupChangedProtocol = true;
258
0
    } else if (scheme.EqualsLiteral("htp")) {
259
0
      // htp -> http.
260
0
      uriString.ReplaceLiteral(0, 3, "http");
261
0
      scheme.AssignLiteral("http");
262
0
      info->mFixupChangedProtocol = true;
263
0
    } else if (scheme.EqualsLiteral("ttps")) {
264
0
      // ttps -> https.
265
0
      uriString.ReplaceLiteral(0, 4, "https");
266
0
      scheme.AssignLiteral("https");
267
0
      info->mFixupChangedProtocol = true;
268
0
    } else if (scheme.EqualsLiteral("tps")) {
269
0
      // tps -> https.
270
0
      uriString.ReplaceLiteral(0, 3, "https");
271
0
      scheme.AssignLiteral("https");
272
0
      info->mFixupChangedProtocol = true;
273
0
    } else if (scheme.EqualsLiteral("ps")) {
274
0
      // ps -> https.
275
0
      uriString.ReplaceLiteral(0, 2, "https");
276
0
      scheme.AssignLiteral("https");
277
0
      info->mFixupChangedProtocol = true;
278
0
    } else if (scheme.EqualsLiteral("htps")) {
279
0
      // htps -> https.
280
0
      uriString.ReplaceLiteral(0, 4, "https");
281
0
      scheme.AssignLiteral("https");
282
0
      info->mFixupChangedProtocol = true;
283
0
    } else if (scheme.EqualsLiteral("ile")) {
284
0
      // ile -> file.
285
0
      uriString.ReplaceLiteral(0, 3, "file");
286
0
      scheme.AssignLiteral("file");
287
0
      info->mFixupChangedProtocol = true;
288
0
    } else if (scheme.EqualsLiteral("le")) {
289
0
      // le -> file.
290
0
      uriString.ReplaceLiteral(0, 2, "file");
291
0
      scheme.AssignLiteral("file");
292
0
      info->mFixupChangedProtocol = true;
293
0
    }
294
0
  }
295
0
296
0
  // Now we need to check whether "scheme" is something we don't
297
0
  // really know about.
298
0
  nsCOMPtr<nsIProtocolHandler> ourHandler, extHandler;
299
0
300
0
  extHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "default");
301
0
  if (!scheme.IsEmpty()) {
302
0
    ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(ourHandler));
303
0
  } else {
304
0
    ourHandler = extHandler;
305
0
  }
306
0
307
0
  if (ourHandler != extHandler || !PossiblyHostPortUrl(uriString)) {
308
0
    // Just try to create an URL out of it
309
0
    rv = NS_NewURI(getter_AddRefs(info->mFixedURI), uriString, nullptr);
310
0
311
0
    if (!info->mFixedURI && rv != NS_ERROR_MALFORMED_URI) {
312
0
      return rv;
313
0
    }
314
0
  }
315
0
316
0
  if (info->mFixedURI && ourHandler == extHandler && sFixupKeywords &&
317
0
      (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) {
318
0
    nsCOMPtr<nsIExternalProtocolService> extProtService =
319
0
      do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
320
0
    if (extProtService) {
321
0
      bool handlerExists = false;
322
0
      rv = extProtService->ExternalProtocolHandlerExists(scheme.get(),
323
0
                                                         &handlerExists);
324
0
      if (NS_FAILED(rv)) {
325
0
        return rv;
326
0
      }
327
0
      // This basically means we're dealing with a theoretically valid
328
0
      // URI... but we have no idea how to load it. (e.g. "christmas:humbug")
329
0
      // It's more likely the user wants to search, and so we
330
0
      // chuck this over to their preferred search provider instead:
331
0
      if (!handlerExists) {
332
0
        bool hasUserPassword = HasUserPassword(uriString);
333
0
        if (!hasUserPassword) {
334
0
          TryKeywordFixupForURIInfo(uriString, info, aPostData);
335
0
        } else {
336
0
          // If the given URL has a user:password we can't just pass it to the
337
0
          // external protocol handler; we'll try using it with http instead later
338
0
          info->mFixedURI = nullptr;
339
0
        }
340
0
      }
341
0
    }
342
0
  }
343
0
344
0
  if (info->mFixedURI) {
345
0
    if (!info->mPreferredURI) {
346
0
      if (aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
347
0
        info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI);
348
0
      }
349
0
      info->mPreferredURI = info->mFixedURI;
350
0
    }
351
0
    return NS_OK;
352
0
  }
353
0
354
0
  // Fix up protocol string before calling KeywordURIFixup, because
355
0
  // it cares about the hostname of such URIs:
356
0
  nsCOMPtr<nsIURI> uriWithProtocol;
357
0
  bool inputHadDuffProtocol = false;
358
0
359
0
  // Prune duff protocol schemes
360
0
  //
361
0
  //   ://totallybroken.url.com
362
0
  //   //shorthand.url.com
363
0
  //
364
0
  if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://"))) {
365
0
    uriString = StringTail(uriString, uriString.Length() - 3);
366
0
    inputHadDuffProtocol = true;
367
0
  } else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//"))) {
368
0
    uriString = StringTail(uriString, uriString.Length() - 2);
369
0
    inputHadDuffProtocol = true;
370
0
  }
371
0
372
0
  // Note: this rv gets returned at the end of this method if we don't fix up
373
0
  // the protocol and don't do a keyword fixup after this (because the pref
374
0
  // or the flags passed might not let us).
375
0
  rv = NS_OK;
376
0
  // Avoid fixing up content that looks like tab-separated values
377
0
  if (!MaybeTabSeparatedContent(uriString)) {
378
0
    rv = FixupURIProtocol(uriString, info, getter_AddRefs(uriWithProtocol));
379
0
    if (uriWithProtocol) {
380
0
      info->mFixedURI = uriWithProtocol;
381
0
    }
382
0
  }
383
0
384
0
  // See if it is a keyword
385
0
  // Test whether keywords need to be fixed up
386
0
  if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) &&
387
0
      !inputHadDuffProtocol) {
388
0
    if (NS_SUCCEEDED(KeywordURIFixup(uriString, info, aPostData)) &&
389
0
        info->mPreferredURI) {
390
0
      return NS_OK;
391
0
    }
392
0
  }
393
0
394
0
  // Did the caller want us to try an alternative URI?
395
0
  // If so, attempt to fixup http://foo into http://www.foo.com
396
0
397
0
  if (info->mFixedURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
398
0
    info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI);
399
0
  }
400
0
401
0
  if (info->mFixedURI) {
402
0
    info->mPreferredURI = info->mFixedURI;
403
0
    return NS_OK;
404
0
  }
405
0
406
0
  // If we still haven't been able to construct a valid URI, try to force a
407
0
  // keyword match.  This catches search strings with '.' or ':' in them.
408
0
  if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) {
409
0
    rv = TryKeywordFixupForURIInfo(aStringURI, info, aPostData);
410
0
  }
411
0
412
0
  return rv;
413
0
}
414
415
NS_IMETHODIMP
416
nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
417
                                nsIInputStream** aPostData,
418
                                nsIURIFixupInfo** aInfo)
419
0
{
420
0
  RefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(aKeyword);
421
0
  NS_ADDREF(*aInfo = info);
422
0
423
0
  if (aPostData) {
424
0
    *aPostData = nullptr;
425
0
  }
426
0
  NS_ENSURE_STATE(Preferences::GetRootBranch());
427
0
428
0
  // Strip leading "?" and leading/trailing spaces from aKeyword
429
0
  nsAutoCString keyword(aKeyword);
430
0
  if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) {
431
0
    keyword.Cut(0, 1);
432
0
  }
433
0
  keyword.Trim(" ");
434
0
435
0
  if (XRE_IsContentProcess()) {
436
0
    dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
437
0
    if (!contentChild) {
438
0
      return NS_ERROR_NOT_AVAILABLE;
439
0
    }
440
0
441
0
    RefPtr<nsIInputStream> postData;
442
0
    ipc::OptionalURIParams uri;
443
0
    nsAutoString providerName;
444
0
    if (!contentChild->SendKeywordToURI(keyword, &providerName, &postData,
445
0
                                        &uri)) {
446
0
      return NS_ERROR_FAILURE;
447
0
    }
448
0
449
0
    CopyUTF8toUTF16(keyword, info->mKeywordAsSent);
450
0
    info->mKeywordProviderName = providerName;
451
0
452
0
    if (aPostData) {
453
0
      postData.forget(aPostData);
454
0
    }
455
0
456
0
    nsCOMPtr<nsIURI> temp = DeserializeURI(uri);
457
0
    info->mPreferredURI = temp.forget();
458
0
    return NS_OK;
459
0
  }
460
0
461
0
#ifdef MOZ_TOOLKIT_SEARCH
462
0
  // Try falling back to the search service's default search engine
463
0
  nsCOMPtr<nsIBrowserSearchService> searchSvc =
464
0
    do_GetService("@mozilla.org/browser/search-service;1");
465
0
  if (searchSvc) {
466
0
    nsCOMPtr<nsISearchEngine> defaultEngine;
467
0
    searchSvc->GetDefaultEngine(getter_AddRefs(defaultEngine));
468
0
    if (defaultEngine) {
469
0
      nsCOMPtr<nsISearchSubmission> submission;
470
0
      nsAutoString responseType;
471
0
      // We allow default search plugins to specify alternate
472
0
      // parameters that are specific to keyword searches.
473
0
      NS_NAMED_LITERAL_STRING(mozKeywordSearch,
474
0
                              "application/x-moz-keywordsearch");
475
0
      bool supportsResponseType = false;
476
0
      defaultEngine->SupportsResponseType(mozKeywordSearch,
477
0
                                          &supportsResponseType);
478
0
      if (supportsResponseType) {
479
0
        responseType.Assign(mozKeywordSearch);
480
0
      }
481
0
482
0
      NS_ConvertUTF8toUTF16 keywordW(keyword);
483
0
      defaultEngine->GetSubmission(keywordW,
484
0
                                   responseType,
485
0
                                   NS_LITERAL_STRING("keyword"),
486
0
                                   getter_AddRefs(submission));
487
0
488
0
      if (submission) {
489
0
        nsCOMPtr<nsIInputStream> postData;
490
0
        submission->GetPostData(getter_AddRefs(postData));
491
0
        if (aPostData) {
492
0
          postData.forget(aPostData);
493
0
        } else if (postData) {
494
0
          // The submission specifies POST data (i.e. the search
495
0
          // engine's "method" is POST), but our caller didn't allow
496
0
          // passing post data back. No point passing back a URL that
497
0
          // won't load properly.
498
0
          return NS_ERROR_FAILURE;
499
0
        }
500
0
501
0
        defaultEngine->GetName(info->mKeywordProviderName);
502
0
        info->mKeywordAsSent = keywordW;
503
0
        return submission->GetUri(getter_AddRefs(info->mPreferredURI));
504
0
      }
505
0
    }
506
0
  }
507
0
#endif
508
0
509
0
  // out of options
510
0
  return NS_ERROR_NOT_AVAILABLE;
511
0
}
512
513
// Helper to deal with passing around uri fixup stuff
514
nsresult
515
nsDefaultURIFixup::TryKeywordFixupForURIInfo(const nsACString& aURIString,
516
                                             nsDefaultURIFixupInfo* aFixupInfo,
517
                                             nsIInputStream** aPostData)
518
0
{
519
0
  nsCOMPtr<nsIURIFixupInfo> keywordInfo;
520
0
  nsresult rv = KeywordToURI(aURIString, aPostData,
521
0
                             getter_AddRefs(keywordInfo));
522
0
  if (NS_SUCCEEDED(rv)) {
523
0
    keywordInfo->GetKeywordProviderName(aFixupInfo->mKeywordProviderName);
524
0
    keywordInfo->GetKeywordAsSent(aFixupInfo->mKeywordAsSent);
525
0
    keywordInfo->GetPreferredURI(getter_AddRefs(aFixupInfo->mPreferredURI));
526
0
  }
527
0
  return rv;
528
0
}
529
530
bool
531
nsDefaultURIFixup::MakeAlternateURI(nsCOMPtr<nsIURI>& aURI)
532
0
{
533
0
  if (!Preferences::GetRootBranch()) {
534
0
    return false;
535
0
  }
536
0
  if (!Preferences::GetBool("browser.fixup.alternate.enabled", true)) {
537
0
    return false;
538
0
  }
539
0
540
0
  // Code only works for http. Not for any other protocol including https!
541
0
  bool isHttp = false;
542
0
  aURI->SchemeIs("http", &isHttp);
543
0
  if (!isHttp) {
544
0
    return false;
545
0
  }
546
0
547
0
  // Security - URLs with user / password info should NOT be fixed up
548
0
  nsAutoCString userpass;
549
0
  aURI->GetUserPass(userpass);
550
0
  if (!userpass.IsEmpty()) {
551
0
    return false;
552
0
  }
553
0
  // Don't fix up hosts with ports
554
0
  int32_t port;
555
0
  aURI->GetPort(&port);
556
0
  if (port != -1) {
557
0
    return false;
558
0
  }
559
0
560
0
  nsAutoCString oldHost;
561
0
  aURI->GetHost(oldHost);
562
0
563
0
  // Don't fix up 'localhost' because that's confusing:
564
0
  if (oldHost.EqualsLiteral("localhost")) {
565
0
    return false;
566
0
  }
567
0
568
0
  nsAutoCString newHost;
569
0
  // Count the dots
570
0
  int32_t numDots = 0;
571
0
  nsReadingIterator<char> iter;
572
0
  nsReadingIterator<char> iterEnd;
573
0
  oldHost.BeginReading(iter);
574
0
  oldHost.EndReading(iterEnd);
575
0
  while (iter != iterEnd) {
576
0
    if (*iter == '.') {
577
0
      numDots++;
578
0
    }
579
0
    ++iter;
580
0
  }
581
0
582
0
  // Get the prefix and suffix to stick onto the new hostname. By default these
583
0
  // are www. & .com but they could be any other value, e.g. www. & .org
584
0
585
0
  nsAutoCString prefix("www.");
586
0
  nsAutoCString prefPrefix;
587
0
  nsresult rv =
588
0
    Preferences::GetCString("browser.fixup.alternate.prefix", prefPrefix);
589
0
  if (NS_SUCCEEDED(rv)) {
590
0
    prefix.Assign(prefPrefix);
591
0
  }
592
0
593
0
  nsAutoCString suffix(".com");
594
0
  nsAutoCString prefSuffix;
595
0
  rv = Preferences::GetCString("browser.fixup.alternate.suffix", prefSuffix);
596
0
  if (NS_SUCCEEDED(rv)) {
597
0
    suffix.Assign(prefSuffix);
598
0
  }
599
0
600
0
  if (numDots == 0) {
601
0
    newHost.Assign(prefix);
602
0
    newHost.Append(oldHost);
603
0
    newHost.Append(suffix);
604
0
  } else if (numDots == 1) {
605
0
    if (!prefix.IsEmpty() &&
606
0
        oldHost.EqualsIgnoreCase(prefix.get(), prefix.Length())) {
607
0
      newHost.Assign(oldHost);
608
0
      newHost.Append(suffix);
609
0
    } else if (!suffix.IsEmpty()) {
610
0
      newHost.Assign(prefix);
611
0
      newHost.Append(oldHost);
612
0
    } else {
613
0
      // Do nothing
614
0
      return false;
615
0
    }
616
0
  } else {
617
0
    // Do nothing
618
0
    return false;
619
0
  }
620
0
621
0
  if (newHost.IsEmpty()) {
622
0
    return false;
623
0
  }
624
0
625
0
  // Assign the new host string over the old one
626
0
  Unused << NS_MutateURI(aURI)
627
0
              .SetHost(newHost)
628
0
              .Finalize(aURI);
629
0
630
0
  return true;
631
0
}
632
633
nsresult
634
nsDefaultURIFixup::FileURIFixup(const nsACString& aStringURI, nsIURI** aURI)
635
0
{
636
0
  nsAutoCString uriSpecOut;
637
0
638
0
  nsresult rv = ConvertFileToStringURI(aStringURI, uriSpecOut);
639
0
  if (NS_SUCCEEDED(rv)) {
640
0
    // if this is file url, uriSpecOut is already in FS charset
641
0
    if (NS_SUCCEEDED(NS_NewURI(aURI, uriSpecOut.get(), nullptr))) {
642
0
      return NS_OK;
643
0
    }
644
0
  }
645
0
  return NS_ERROR_FAILURE;
646
0
}
647
648
nsresult
649
nsDefaultURIFixup::ConvertFileToStringURI(const nsACString& aIn,
650
                                          nsCString& aResult)
651
0
{
652
0
  bool attemptFixup = false;
653
0
654
#if defined(XP_WIN)
655
  // Check for \ in the url-string or just a drive (PC)
656
  if (aIn.Contains('\\') ||
657
      (aIn.Length() == 2 && (aIn.Last() == ':' || aIn.Last() == '|'))) {
658
    attemptFixup = true;
659
  }
660
#elif defined(XP_UNIX)
661
  // Check if it starts with / (UNIX)
662
0
  if (aIn.First() == '/') {
663
0
    attemptFixup = true;
664
0
  }
665
#else
666
  // Do nothing (All others for now)
667
#endif
668
669
0
  if (attemptFixup) {
670
0
    // Test if this is a valid path by trying to create a local file
671
0
    // object. The URL of that is returned if successful.
672
0
673
0
    nsCOMPtr<nsIFile> filePath;
674
0
    nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(aIn), false,
675
0
                                  getter_AddRefs(filePath));
676
0
677
0
    if (NS_SUCCEEDED(rv)) {
678
0
      NS_GetURLSpecFromFile(filePath, aResult);
679
0
      return NS_OK;
680
0
    }
681
0
  }
682
0
683
0
  return NS_ERROR_FAILURE;
684
0
}
685
686
nsresult
687
nsDefaultURIFixup::FixupURIProtocol(const nsACString& aURIString,
688
                                    nsDefaultURIFixupInfo* aFixupInfo,
689
                                    nsIURI** aURI)
690
0
{
691
0
  nsAutoCString uriString(aURIString);
692
0
  *aURI = nullptr;
693
0
694
0
  // Add ftp:// or http:// to front of url if it has no spec
695
0
  //
696
0
  // Should fix:
697
0
  //
698
0
  //   no-scheme.com
699
0
  //   ftp.no-scheme.com
700
0
  //   ftp4.no-scheme.com
701
0
  //   no-scheme.com/query?foo=http://www.foo.com
702
0
  //   user:pass@no-scheme.com
703
0
  //
704
0
  int32_t schemeDelim = uriString.Find("://");
705
0
  int32_t firstDelim = uriString.FindCharInSet("/:");
706
0
  if (schemeDelim <= 0 ||
707
0
      (firstDelim != -1 && schemeDelim > firstDelim)) {
708
0
    // find host name
709
0
    int32_t hostPos = uriString.FindCharInSet("/:?#");
710
0
    if (hostPos == -1) {
711
0
      hostPos = uriString.Length();
712
0
    }
713
0
714
0
    // extract host name
715
0
    nsAutoCString hostSpec;
716
0
    uriString.Left(hostSpec, hostPos);
717
0
718
0
    // insert url spec corresponding to host name
719
0
    uriString.InsertLiteral("http://", 0);
720
0
    aFixupInfo->mFixupChangedProtocol = true;
721
0
  } // end if checkprotocol
722
0
723
0
  return NS_NewURI(aURI, uriString, nullptr);
724
0
}
725
726
bool
727
nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString& aUrl)
728
0
{
729
0
  // Oh dear, the protocol is invalid. Test if the protocol might
730
0
  // actually be a url without a protocol:
731
0
  //
732
0
  //   http://www.faqs.org/rfcs/rfc1738.html
733
0
  //   http://www.faqs.org/rfcs/rfc2396.html
734
0
  //
735
0
  // e.g. Anything of the form:
736
0
  //
737
0
  //   <hostname>:<port> or
738
0
  //   <hostname>:<port>/
739
0
  //
740
0
  // Where <hostname> is a string of alphanumeric characters and dashes
741
0
  // separated by dots.
742
0
  // and <port> is a 5 or less digits. This actually breaks the rfc2396
743
0
  // definition of a scheme which allows dots in schemes.
744
0
  //
745
0
  // Note:
746
0
  //   People expecting this to work with
747
0
  //   <user>:<password>@<host>:<port>/<url-path> will be disappointed!
748
0
  //
749
0
  // Note: Parser could be a lot tighter, tossing out silly hostnames
750
0
  //       such as those containing consecutive dots and so on.
751
0
752
0
  // Read the hostname which should of the form
753
0
  // [a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*:
754
0
755
0
  nsACString::const_iterator iterBegin;
756
0
  nsACString::const_iterator iterEnd;
757
0
  aUrl.BeginReading(iterBegin);
758
0
  aUrl.EndReading(iterEnd);
759
0
  nsACString::const_iterator iter = iterBegin;
760
0
761
0
  while (iter != iterEnd) {
762
0
    uint32_t chunkSize = 0;
763
0
    // Parse a chunk of the address
764
0
    while (iter != iterEnd &&
765
0
           (*iter == '-' ||
766
0
            IsAsciiAlpha(*iter) ||
767
0
            IsAsciiDigit(*iter))) {
768
0
      ++chunkSize;
769
0
      ++iter;
770
0
    }
771
0
    if (chunkSize == 0 || iter == iterEnd) {
772
0
      return false;
773
0
    }
774
0
    if (*iter == ':') {
775
0
      // Go onto checking the for the digits
776
0
      break;
777
0
    }
778
0
    if (*iter != '.') {
779
0
      // Whatever it is, it ain't a hostname!
780
0
      return false;
781
0
    }
782
0
    ++iter;
783
0
  }
784
0
  if (iter == iterEnd) {
785
0
    // No point continuing since there is no colon
786
0
    return false;
787
0
  }
788
0
  ++iter;
789
0
790
0
  // Count the number of digits after the colon and before the
791
0
  // next forward slash (or end of string)
792
0
793
0
  uint32_t digitCount = 0;
794
0
  while (iter != iterEnd && digitCount <= 5) {
795
0
    if (IsAsciiDigit(*iter)) {
796
0
      digitCount++;
797
0
    } else if (*iter == '/') {
798
0
      break;
799
0
    } else {
800
0
      // Whatever it is, it ain't a port!
801
0
      return false;
802
0
    }
803
0
    ++iter;
804
0
  }
805
0
  if (digitCount == 0 || digitCount > 5) {
806
0
    // No digits or more digits than a port would have.
807
0
    return false;
808
0
  }
809
0
810
0
  // Yes, it's possibly a host:port url
811
0
  return true;
812
0
}
813
814
nsresult
815
nsDefaultURIFixup::KeywordURIFixup(const nsACString& aURIString,
816
                                   nsDefaultURIFixupInfo* aFixupInfo,
817
                                   nsIInputStream** aPostData)
818
0
{
819
0
  // These are keyword formatted strings
820
0
  // "what is mozilla"
821
0
  // "what is mozilla?"
822
0
  // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
823
0
  // "?mozilla" - anything that begins with a question mark
824
0
  // "?site:mozilla.org docshell"
825
0
  // Things that have a quote before the first dot/colon
826
0
  // "mozilla" - checked against a whitelist to see if it's a host or not
827
0
  // ".mozilla", "mozilla." - ditto
828
0
829
0
  // These are not keyword formatted strings
830
0
  // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?"
831
0
  // "www.blah.com stuff"
832
0
  // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?"
833
0
  // "nonQualifiedHost:80 args"
834
0
  // "nonQualifiedHost?"
835
0
  // "nonQualifiedHost?args"
836
0
  // "nonQualifiedHost?some args"
837
0
  // "blah.com."
838
0
839
0
  // Note: uint32_t(kNotFound) is greater than any actual location
840
0
  // in practice.  So if we cast all locations to uint32_t, then a <
841
0
  // b guarantees that either b is kNotFound and a is found, or both
842
0
  // are found and a found before b.
843
0
844
0
  uint32_t firstDotLoc = uint32_t(kNotFound);
845
0
  uint32_t lastDotLoc = uint32_t(kNotFound);
846
0
  uint32_t firstColonLoc = uint32_t(kNotFound);
847
0
  uint32_t firstQuoteLoc = uint32_t(kNotFound);
848
0
  uint32_t firstSpaceLoc = uint32_t(kNotFound);
849
0
  uint32_t firstQMarkLoc = uint32_t(kNotFound);
850
0
  uint32_t lastLSBracketLoc = uint32_t(kNotFound);
851
0
  uint32_t lastSlashLoc = uint32_t(kNotFound);
852
0
  uint32_t pos = 0;
853
0
  uint32_t foundDots = 0;
854
0
  uint32_t foundColons = 0;
855
0
  uint32_t foundDigits = 0;
856
0
  uint32_t foundRSBrackets = 0;
857
0
  bool looksLikeIpv6 = true;
858
0
  bool hasAsciiAlpha = false;
859
0
860
0
  nsACString::const_iterator iterBegin;
861
0
  nsACString::const_iterator iterEnd;
862
0
  aURIString.BeginReading(iterBegin);
863
0
  aURIString.EndReading(iterEnd);
864
0
  nsACString::const_iterator iter = iterBegin;
865
0
866
0
  while (iter != iterEnd) {
867
0
    if (pos >= 1 && foundRSBrackets == 0) {
868
0
      if (!(lastLSBracketLoc == 0 &&
869
0
            (*iter == ':' ||
870
0
             *iter == '.' ||
871
0
             *iter == ']' ||
872
0
             (*iter >= 'a' && *iter <= 'f') ||
873
0
             (*iter >= 'A' && *iter <= 'F') ||
874
0
             IsAsciiDigit(*iter)))) {
875
0
        looksLikeIpv6 = false;
876
0
      }
877
0
    }
878
0
879
0
    // If we're at the end of the string or this is the first slash,
880
0
    // check if the thing before the slash looks like ipv4:
881
0
    if ((iterEnd - iter == 1 ||
882
0
         (lastSlashLoc == uint32_t(kNotFound) && *iter == '/')) &&
883
0
        // Need 2 or 3 dots + only digits
884
0
        (foundDots == 2 || foundDots == 3) &&
885
0
        // and they should be all that came before now:
886
0
        (foundDots + foundDigits == pos ||
887
0
         // or maybe there was also exactly 1 colon that came after the last dot,
888
0
         // and the digits, dots and colon were all that came before now:
889
0
         (foundColons == 1 && firstColonLoc > lastDotLoc &&
890
0
          foundDots + foundDigits + foundColons == pos))) {
891
0
      // Hurray, we got ourselves some ipv4!
892
0
      // At this point, there's no way we will do a keyword lookup, so just bail immediately:
893
0
      return NS_OK;
894
0
    }
895
0
896
0
    if (*iter == '.') {
897
0
      ++foundDots;
898
0
      lastDotLoc = pos;
899
0
      if (firstDotLoc == uint32_t(kNotFound)) {
900
0
        firstDotLoc = pos;
901
0
      }
902
0
    } else if (*iter == ':') {
903
0
      ++foundColons;
904
0
      if (firstColonLoc == uint32_t(kNotFound)) {
905
0
        firstColonLoc = pos;
906
0
      }
907
0
    } else if (*iter == ' ' && firstSpaceLoc == uint32_t(kNotFound)) {
908
0
      firstSpaceLoc = pos;
909
0
    } else if (*iter == '?' && firstQMarkLoc == uint32_t(kNotFound)) {
910
0
      firstQMarkLoc = pos;
911
0
    } else if ((*iter == '\'' || *iter == '"') &&
912
0
               firstQuoteLoc == uint32_t(kNotFound)) {
913
0
      firstQuoteLoc = pos;
914
0
    } else if (*iter == '[') {
915
0
      lastLSBracketLoc = pos;
916
0
    } else if (*iter == ']') {
917
0
      foundRSBrackets++;
918
0
    } else if (*iter == '/') {
919
0
      lastSlashLoc = pos;
920
0
    } else if (IsAsciiAlpha(*iter)) {
921
0
      hasAsciiAlpha = true;
922
0
    } else if (IsAsciiDigit(*iter)) {
923
0
      ++foundDigits;
924
0
    }
925
0
926
0
    pos++;
927
0
    iter++;
928
0
  }
929
0
930
0
  if (lastLSBracketLoc > 0 || foundRSBrackets != 1) {
931
0
    looksLikeIpv6 = false;
932
0
  }
933
0
934
0
  // If there are only colons and only hexadecimal characters ([a-z][0-9])
935
0
  // enclosed in [], then don't do a keyword lookup
936
0
  if (looksLikeIpv6) {
937
0
    return NS_OK;
938
0
  }
939
0
940
0
  nsAutoCString asciiHost;
941
0
  nsAutoCString displayHost;
942
0
943
0
  bool isValidHost =
944
0
    aFixupInfo->mFixedURI &&
945
0
    NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) &&
946
0
    !asciiHost.IsEmpty();
947
0
948
0
  bool isValidDisplayHost =
949
0
    aFixupInfo->mFixedURI &&
950
0
    NS_SUCCEEDED(aFixupInfo->mFixedURI->GetDisplayHost(displayHost)) &&
951
0
    !displayHost.IsEmpty();
952
0
953
0
  nsresult rv = NS_OK;
954
0
  // We do keyword lookups if a space or quote preceded the dot, colon
955
0
  // or question mark (or if the latter is not found, or if the input starts
956
0
  // with a question mark)
957
0
  if (((firstSpaceLoc < firstDotLoc || firstQuoteLoc < firstDotLoc) &&
958
0
       (firstSpaceLoc < firstColonLoc || firstQuoteLoc < firstColonLoc) &&
959
0
       (firstSpaceLoc < firstQMarkLoc || firstQuoteLoc < firstQMarkLoc)) ||
960
0
      firstQMarkLoc == 0) {
961
0
    rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo,
962
0
                                   aPostData);
963
0
    // ... or when the asciiHost is the same as displayHost and there are no
964
0
    // characters from [a-z][A-Z]
965
0
  } else if (isValidHost && isValidDisplayHost && !hasAsciiAlpha &&
966
0
             asciiHost.EqualsIgnoreCase(displayHost.get())) {
967
0
    if (!sDNSFirstForSingleWords) {
968
0
      rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo,
969
0
                                     aPostData);
970
0
    }
971
0
  }
972
0
  // ... or if there is no question mark or colon, and there is either no
973
0
  // dot, or exactly 1 and it is the first or last character of the input:
974
0
  else if ((firstDotLoc == uint32_t(kNotFound) ||
975
0
            (foundDots == 1 && (firstDotLoc == 0 ||
976
0
                                firstDotLoc == aURIString.Length() - 1))) &&
977
0
           firstColonLoc == uint32_t(kNotFound) &&
978
0
           firstQMarkLoc == uint32_t(kNotFound)) {
979
0
    if (isValidHost && IsDomainWhitelisted(asciiHost, firstDotLoc)) {
980
0
      return NS_OK;
981
0
    }
982
0
983
0
    // ... unless there are no dots, and a slash, and alpha characters, and
984
0
    // this is a valid host:
985
0
    if (firstDotLoc == uint32_t(kNotFound) &&
986
0
        lastSlashLoc != uint32_t(kNotFound) &&
987
0
        hasAsciiAlpha && isValidHost) {
988
0
      return NS_OK;
989
0
    }
990
0
991
0
    // If we get here, we don't have a valid URI, or we did but the
992
0
    // host is not whitelisted, so we do a keyword search *anyway*:
993
0
    rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo,
994
0
                                   aPostData);
995
0
  }
996
0
  return rv;
997
0
}
998
999
bool
1000
nsDefaultURIFixup::IsDomainWhitelisted(const nsACString& aAsciiHost,
1001
                                       const uint32_t aDotLoc)
1002
0
{
1003
0
  if (sDNSFirstForSingleWords) {
1004
0
    return true;
1005
0
  }
1006
0
  // Check if this domain is whitelisted as an actual
1007
0
  // domain (which will prevent a keyword query)
1008
0
  // NB: any processing of the host here should stay in sync with
1009
0
  // code in the front-end(s) that set the pref.
1010
0
1011
0
  nsAutoCString pref("browser.fixup.domainwhitelist.");
1012
0
1013
0
  if (aDotLoc == aAsciiHost.Length() - 1) {
1014
0
    pref.Append(Substring(aAsciiHost, 0, aAsciiHost.Length() - 1));
1015
0
  } else {
1016
0
    pref.Append(aAsciiHost);
1017
0
  }
1018
0
1019
0
  return Preferences::GetBool(pref.get(), false);
1020
0
}
1021
1022
NS_IMETHODIMP
1023
nsDefaultURIFixup::IsDomainWhitelisted(const nsACString& aDomain,
1024
                                       const uint32_t aDotLoc,
1025
                                       bool* aResult)
1026
0
{
1027
0
  *aResult = IsDomainWhitelisted(aDomain, aDotLoc);
1028
0
  return NS_OK;
1029
0
}
1030
1031
/* Implementation of nsIURIFixupInfo */
1032
NS_IMPL_ISUPPORTS(nsDefaultURIFixupInfo, nsIURIFixupInfo)
1033
1034
nsDefaultURIFixupInfo::nsDefaultURIFixupInfo(const nsACString& aOriginalInput)
1035
  : mFixupChangedProtocol(false)
1036
  , mFixupCreatedAlternateURI(false)
1037
0
{
1038
0
  mOriginalInput = aOriginalInput;
1039
0
}
1040
1041
nsDefaultURIFixupInfo::~nsDefaultURIFixupInfo()
1042
0
{
1043
0
}
1044
1045
NS_IMETHODIMP
1046
nsDefaultURIFixupInfo::GetConsumer(nsISupports** aConsumer)
1047
0
{
1048
0
  *aConsumer = mConsumer;
1049
0
  NS_IF_ADDREF(*aConsumer);
1050
0
  return NS_OK;
1051
0
}
1052
1053
NS_IMETHODIMP
1054
nsDefaultURIFixupInfo::SetConsumer(nsISupports* aConsumer)
1055
0
{
1056
0
  mConsumer = aConsumer;
1057
0
  return NS_OK;
1058
0
}
1059
1060
NS_IMETHODIMP
1061
nsDefaultURIFixupInfo::GetPreferredURI(nsIURI** aPreferredURI)
1062
0
{
1063
0
  *aPreferredURI = mPreferredURI;
1064
0
  NS_IF_ADDREF(*aPreferredURI);
1065
0
  return NS_OK;
1066
0
}
1067
1068
NS_IMETHODIMP
1069
nsDefaultURIFixupInfo::GetFixedURI(nsIURI** aFixedURI)
1070
0
{
1071
0
  *aFixedURI = mFixedURI;
1072
0
  NS_IF_ADDREF(*aFixedURI);
1073
0
  return NS_OK;
1074
0
}
1075
1076
NS_IMETHODIMP
1077
nsDefaultURIFixupInfo::GetKeywordProviderName(nsAString& aResult)
1078
0
{
1079
0
  aResult = mKeywordProviderName;
1080
0
  return NS_OK;
1081
0
}
1082
1083
NS_IMETHODIMP
1084
nsDefaultURIFixupInfo::GetKeywordAsSent(nsAString& aResult)
1085
0
{
1086
0
  aResult = mKeywordAsSent;
1087
0
  return NS_OK;
1088
0
}
1089
1090
NS_IMETHODIMP
1091
nsDefaultURIFixupInfo::GetFixupChangedProtocol(bool* aResult)
1092
0
{
1093
0
  *aResult = mFixupChangedProtocol;
1094
0
  return NS_OK;
1095
0
}
1096
1097
NS_IMETHODIMP
1098
nsDefaultURIFixupInfo::GetFixupCreatedAlternateURI(bool* aResult)
1099
0
{
1100
0
  *aResult = mFixupCreatedAlternateURI;
1101
0
  return NS_OK;
1102
0
}
1103
1104
NS_IMETHODIMP
1105
nsDefaultURIFixupInfo::GetOriginalInput(nsACString& aResult)
1106
0
{
1107
0
  aResult = mOriginalInput;
1108
0
  return NS_OK;
1109
0
}