nsDefaultURIFixup.cpp 36 KB

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