Bug 1496578 - convert nsDefaultURIFixup to URIFixup.jsm. r=Gijs,farre

Differential Revision: https://phabricator.services.mozilla.com/D66579

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Marco Bonardo 2020-04-07 21:55:24 +00:00
parent 37b364e264
commit 7457a384f2
18 changed files with 1099 additions and 1227 deletions

View File

@ -104,6 +104,15 @@ class UrlbarValueFormatter {
}
let url = this.inputField.value;
let browser = this.window.gBrowser.selectedBrowser;
// Since doing a full URIFixup and offset calculations is expensive, we
// keep the metadata cached in the browser itself, so when switching tabs
// we can skip most of this.
if (browser._urlMetaData && browser._urlMetaData.url == url) {
return browser._urlMetaData.data;
}
browser._urlMetaData = { url, data: null };
// Get the URL from the fixup service:
let flags =
@ -175,7 +184,14 @@ class UrlbarValueFormatter {
}
}
return { preDomain, schemeWSlashes, domain, url, uriInfo, trimmedLength };
return (browser._urlMetaData.data = {
domain,
origin: uriInfo.fixedURI.host,
preDomain,
schemeWSlashes,
trimmedLength,
url,
});
}
_removeURLFormat() {
@ -209,12 +225,12 @@ class UrlbarValueFormatter {
}
let {
url,
uriInfo,
domain,
origin,
preDomain,
schemeWSlashes,
domain,
trimmedLength,
url,
} = urlMetaData;
// We strip http, so we should not show the scheme box for it.
if (!UrlbarPrefs.get("trimURLs") || schemeWSlashes != "http://") {
@ -258,7 +274,7 @@ class UrlbarValueFormatter {
let baseDomain = domain;
let subDomain = "";
try {
baseDomain = Services.eTLD.getBaseDomainFromHost(uriInfo.fixedURI.host);
baseDomain = Services.eTLD.getBaseDomainFromHost(origin);
if (!domain.endsWith(baseDomain)) {
// getBaseDomainFromHost converts its resultant to ACE.
let IDNService = Cc["@mozilla.org/network/idn-service;1"].getService(

View File

@ -247,8 +247,6 @@ void CanonicalBrowsingContext::UpdateMediaControlKeysEvent(
void CanonicalBrowsingContext::LoadURI(const nsAString& aURI,
const LoadURIOptions& aOptions,
ErrorResult& aError) {
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
nsCOMPtr<nsISupports> consumer = GetDocShell();
if (!consumer) {
consumer = GetEmbedderElement();
@ -260,7 +258,7 @@ void CanonicalBrowsingContext::LoadURI(const nsAString& aURI,
RefPtr<nsDocShellLoadState> loadState;
nsresult rv = nsDocShellLoadState::CreateFromLoadURIOptions(
consumer, uriFixup, aURI, aOptions, getter_AddRefs(loadState));
consumer, aURI, aOptions, getter_AddRefs(loadState));
if (rv == NS_ERROR_MALFORMED_URI) {
DisplayLoadError(aURI);

907
docshell/base/URIFixup.jsm Normal file
View File

@ -0,0 +1,907 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* vim: sw=2 ts=2 sts=2 expandtab
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This component handles fixing up URIs, by correcting obvious typos and adding
* missing schemes.
*/
// TODO (Bug 1623383): This is a direct conversion from .cpp, as such a few
// functions are overly complex and should be cleaned up.
/* eslint complexity: ["error", 63] */
var EXPORTED_SYMBOLS = ["URIFixup", "URIFixupInfo"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"externalProtocolService",
"@mozilla.org/uriloader/external-protocol-service;1",
"nsIExternalProtocolService"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"defaultProtocolHandler",
"@mozilla.org/network/protocol;1?name=default",
"nsIProtocolHandler"
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"fixupSchemeTypos",
"browser.fixup.typo.scheme",
true
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"dnsFirstForSingleWords",
"browser.fixup.dns_first_for_single_words",
false
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"keywordEnabled",
"keyword.enabled",
true
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"alternateEnabled",
"browser.fixup.alternate.enabled",
true
);
const {
FIXUP_FLAG_NONE,
FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
FIXUP_FLAGS_MAKE_ALTERNATE_URI,
FIXUP_FLAG_PRIVATE_CONTEXT,
FIXUP_FLAG_FIX_SCHEME_TYPOS,
} = Ci.nsIURIFixup;
const COMMON_PROTOCOLS = ["http", "https", "ftp", "file"];
// Regex used to identify user:password tokens in url strings.
// This is not a strict character check, because we try to fixup this part of
// a the url too.
XPCOMUtils.defineLazyGetter(
this,
"userPasswordRegex",
() => /^([a-z+.-]+:\/{0,3})*[^\/@]+@.+/i
);
// Regex used to identify ascii alphabetical characters.
XPCOMUtils.defineLazyGetter(this, "asciiAlphaRegex", () => /^[a-z]$/i);
// Regex used to identify ascii a-f characters.
XPCOMUtils.defineLazyGetter(this, "asciiHexRegex", () => /^[a-f0-9]$/i);
// Regex used to identify ascii numerical characters.
XPCOMUtils.defineLazyGetter(this, "asciiDigitRegex", () => /^[0-9]$/);
// Regex used to identify tab separated content (having at least 2 tabs).
XPCOMUtils.defineLazyGetter(this, "maxOneTabRegex", () => /^[^\t]*\t?[^\t]*$/);
// Regex to test if the protocol might actually be a url without a protocol:
//
// http://www.faqs.org/rfcs/rfc1738.html
// http://www.faqs.org/rfcs/rfc2396.html
//
// e.g. Anything of the form:
//
// <hostname>:<port> or
// <hostname>:<port>/
//
// Where <hostname> is a string of alphanumeric characters and dashes
// separated by dots.
// and <port> is a 5 or less digits. This actually breaks the rfc2396
// definition of a scheme which allows dots in schemes.
//
// Note:
// People expecting this to work with
// <user>:<password>@<host>:<port>/<url-path> will be disappointed!
//
// Note: Parser could be a lot tighter, tossing out silly hostnames
// such as those containing consecutive dots and so on.
XPCOMUtils.defineLazyGetter(
this,
"possiblyHostPortRegex",
() => /^[a-z0-9-]+(\.[a-z0-9-]+)*:[0-9]{1,5}([/?#]|$)/i
);
// Regex used to strip newlines.
XPCOMUtils.defineLazyGetter(this, "newLinesRegex", () => /[\r\n]/g);
// Regex used to match a possible protocol.
// This resembles the logic in Services.io.extractScheme, thus \t is admitted
// and stripped later. We don't use Services.io.extractScheme because of
// performance bottleneck caused by crossing XPConnect.
XPCOMUtils.defineLazyGetter(
this,
"possibleProtocolRegex",
() => /^([a-z][a-z0-9.+\t-]*):/i
);
// Cache of whitelisted domains.
XPCOMUtils.defineLazyGetter(this, "domainsWhitelist", () => {
let domains = new Set(
Services.prefs
.getChildList("browser.fixup.domainwhitelist.")
.filter(p => Services.prefs.getBoolPref(p, false))
.map(p => p.substring(30))
);
// Hold onto the observer.
domains._observer = {
observe(subject, topic, data) {
let domain = data.substring(30);
if (Services.prefs.getBoolPref(data, false)) {
domains.add(domain);
} else {
domains.delete(domain);
}
},
QueryInterface: ChromeUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
};
Services.prefs.addObserver(
"browser.fixup.domainwhitelist.",
domains._observer,
true
);
return domains;
});
function URIFixup() {}
URIFixup.prototype = {
get FIXUP_FLAG_NONE() {
return FIXUP_FLAG_NONE;
},
get FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP() {
return FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
},
get FIXUP_FLAGS_MAKE_ALTERNATE_URI() {
return FIXUP_FLAGS_MAKE_ALTERNATE_URI;
},
get FIXUP_FLAG_PRIVATE_CONTEXT() {
return FIXUP_FLAG_PRIVATE_CONTEXT;
},
get FIXUP_FLAG_FIX_SCHEME_TYPOS() {
return FIXUP_FLAG_FIX_SCHEME_TYPOS;
},
createFixupURI(uriString, fixupFlags = FIXUP_FLAG_NONE, postData) {
return this.getFixupURIInfo(uriString, fixupFlags, postData).preferredURI;
},
getFixupURIInfo(uriString, fixupFlags = FIXUP_FLAG_NONE, postData) {
let isPrivateContext = fixupFlags & FIXUP_FLAG_PRIVATE_CONTEXT;
// Eliminate embedded newlines, which single-line text fields now allow,
// and cleanup the empty spaces and tabs that might be on each end.
uriString = uriString.trim().replace(newLinesRegex, "");
if (!uriString) {
throw new Components.Exception(
"Should pass a non-null uri",
Cr.NS_ERROR_FAILURE
);
}
let info = new URIFixupInfo(uriString);
let scheme = extractScheme(uriString);
let isCommonProtocol = COMMON_PROTOCOLS.includes(scheme);
// View-source is a pseudo scheme. We're interested in fixing up the stuff
// after it. The easiest way to do that is to call this method again with
// the "view-source:" lopped off and then prepend it again afterwards.
if (scheme == "view-source") {
// We disable keyword lookup and alternate URIs so that small typos don't
// cause us to look at very different domains.
let newFixupFlags =
fixupFlags &
~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP &
~FIXUP_FLAGS_MAKE_ALTERNATE_URI;
let innerURIString = uriString.substring(12).trim();
// Prevent recursion.
let innerScheme = extractScheme(innerURIString);
if (innerScheme == "view-source") {
throw new Components.Exception(
"Prevent view-source recursion",
Cr.NS_ERROR_FAILURE
);
}
let innerInfo = this.getFixupURIInfo(
innerURIString,
newFixupFlags,
postData
);
if (!innerInfo.preferredURI) {
throw new Components.Exception("No preferredURI", Cr.NS_ERROR_FAILURE);
}
info.fixedURI = Services.io.newURI(
"view-source:" + innerInfo.preferredURI.spec
);
info.preferredURI = info.fixedURI;
return info;
}
if (scheme.length < 2) {
// Check if it is a file path. We skip most schemes because the only case
// where a file path may look like having a scheme is "X:" on Windows.
let fileURI = fileURIFixup(uriString);
if (fileURI) {
info.fixedURI = info.preferredURI = fileURI;
info.fixupChangedProtocol = true;
return info;
}
}
// Fix up common scheme typos.
// TODO: Use levenshtein distance here?
if (
fixupSchemeTypos &&
fixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS &&
scheme &&
!isCommonProtocol
) {
for (let [typo, fixed] of [
["ttp", "http"],
["htp", "http"],
["ttps", "https"],
["tps", "https"],
["ps", "https"],
["htps", "https"],
["ile", "file"],
["le", "file"],
]) {
if (uriString.startsWith(typo)) {
scheme = fixed;
uriString = scheme + uriString.substring(typo.length);
isCommonProtocol = true;
break;
}
}
}
// Now we need to check whether "scheme" is something we don't
// really know about.
let isDefaultProtocolHandler =
!isCommonProtocol &&
scheme &&
Services.io.getProtocolHandler(scheme) == defaultProtocolHandler;
if (!isDefaultProtocolHandler || !possiblyHostPortRegex.test(uriString)) {
// Just try to create an URL out of it.
try {
info.fixedURI = Services.io.newURI(uriString);
} catch (ex) {
if (ex.result != Cr.NS_ERROR_MALFORMED_URI) {
throw ex;
}
}
}
// TODO (Bug 1588118): Should check FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
// instead of FIXUP_FLAG_FIX_SCHEME_TYPOS.
if (
info.fixedURI &&
isDefaultProtocolHandler &&
keywordEnabled &&
fixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS &&
scheme &&
!externalProtocolService.externalProtocolHandlerExists(scheme)
) {
if (!userPasswordRegex.test(uriString)) {
// This basically means we're dealing with a theoretically valid
// URI... but we have no idea how to load it. (e.g. "christmas:humbug")
// It's more likely the user wants to search, and so we
// chuck this over to their preferred search provider instead:
tryKeywordFixupForURIInfo(uriString, info, isPrivateContext, postData);
} else {
// If the given URL has a user:password we can't just pass it to the
// external protocol handler; we'll try using it with http instead
// later
info.fixedURI = null;
}
}
if (info.fixedURI) {
if (!info.preferredURI) {
if (fixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
info.fixupCreatedAlternateURI = makeAlternateFixedURI(info);
}
info.preferredURI = info.fixedURI;
}
return info;
}
// Fix up protocol string before calling KeywordURIFixup, because
// it cares about the hostname of such URIs.
// Prune duff protocol schemes:
// ://totallybroken.url.com
// //shorthand.url.com
let inputHadDuffProtocol = false;
if (!scheme) {
if (uriString.startsWith("://")) {
uriString = uriString.substring(3);
inputHadDuffProtocol = true;
} else if (uriString.startsWith("//")) {
uriString = uriString.substring(2);
inputHadDuffProtocol = true;
}
}
// Avoid fixing up content that looks like tab-separated values.
// Assume that 1 tab is accidental, but more than 1 implies this is
// supposed to be tab-separated content.
if (!isCommonProtocol && maxOneTabRegex.test(uriString)) {
let uriWithProtocol = fixupURIProtocol(uriString, info);
if (uriWithProtocol) {
info.fixedURI = uriWithProtocol;
}
}
// See if it is a keyword and whether a keyword must be fixed up.
if (
keywordEnabled &&
fixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP &&
!inputHadDuffProtocol
) {
keywordURIFixup(uriString, info, isPrivateContext, postData);
if (info.preferredURI) {
return info;
}
}
// Did the caller want us to try an alternative URI?
// If so, attempt to fixup http://foo into http://www.foo.com
if (info.fixedURI && fixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
info.fixupCreatedAlternateURI = makeAlternateFixedURI(info);
}
if (info.fixedURI) {
info.preferredURI = info.fixedURI;
return info;
}
// If we still haven't been able to construct a valid URI, try to force a
// keyword match. This catches search strings with '.' or ':' in them.
if (keywordEnabled && fixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) {
tryKeywordFixupForURIInfo(
info.originalInput,
info,
isPrivateContext,
postData
);
}
if (!info.preferredURI) {
// we couldn't salvage anything.
throw new Components.Exception(
"Couldn't build a valid uri",
Cr.NS_ERROR_MALFORMED_URI
);
}
return info;
},
webNavigationFlagsToFixupFlags(href, navigationFlags) {
try {
Services.io.newURI(href);
// Remove LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP for valid uris.
navigationFlags &= ~Ci.nsIWebNavigation
.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
} catch (ex) {}
let fixupFlags = FIXUP_FLAG_NONE;
if (
navigationFlags & Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP
) {
fixupFlags |= FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
}
if (navigationFlags & Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS) {
fixupFlags |= FIXUP_FLAG_FIX_SCHEME_TYPOS;
}
return fixupFlags;
},
keywordToURI(keyword, isPrivateContext, postData) {
if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
// There's no search service in the content process, thus all the calls
// from it that care about keywords conversion should go through the
// parent process.
throw new Components.Exception(
"Can't invoke URIFixup in the content process",
Cr.NS_ERROR_NOT_AVAILABLE
);
}
let info = new URIFixupInfo(keyword);
// Strip leading "?" and leading/trailing spaces from aKeyword
if (keyword.startsWith("?")) {
keyword = keyword.substring(1);
}
keyword = keyword.trim();
// Try falling back to the search service's default search engine
// We must use an appropriate search engine depending on the private
// context.
let engine = isPrivateContext
? Services.search.defaultPrivateEngine
: Services.search.defaultEngine;
// We allow default search plugins to specify alternate parameters that are
// specific to keyword searches.
let responseType = null;
if (engine.supportsResponseType("application/x-moz-keywordsearch")) {
responseType = "application/x-moz-keywordsearch";
}
let submission = engine.getSubmission(keyword, responseType, "keyword");
if (!submission) {
throw new Components.Exception(
"Invalid search submission",
Cr.NS_ERROR_NOT_AVAILABLE
);
}
let submissionPostDataStream = submission.postData;
if (submissionPostDataStream) {
if (postData) {
// TODO (Bug 1626016): instead of having postData as an optional out
// argument, it could be part of URIFixupInfo.
postData.value = submissionPostDataStream;
} else {
// The submission specifies POST data (i.e. the search
// engine's "method" is POST), but our caller didn't allow
// passing post data back. No point passing back a URL that
// won't load properly.
throw new Components.Exception(
"Didn't request POST data",
Cr.NS_ERROR_NOT_AVAILABLE
);
}
}
info.keywordProviderName = engine.name;
info.keywordAsSent = keyword;
info.preferredURI = submission.uri;
return info;
},
isDomainWhitelisted(asciiHost, dotLoc) {
if (dnsFirstForSingleWords) {
return true;
}
// Check if this domain is whitelisted as an actual
// domain (which will prevent a keyword query)
// NB: any processing of the host here should stay in sync with
// code in the front-end(s) that set the pref.
if (dotLoc == asciiHost.length - 1) {
asciiHost = asciiHost.substring(0, asciiHost.length - 1);
}
return domainsWhitelist.has(asciiHost);
},
classID: Components.ID("{c6cf88b7-452e-47eb-bdc9-86e3561648ef}"),
_xpcom_factory: XPCOMUtils.generateSingletonFactory(URIFixup),
QueryInterface: ChromeUtils.generateQI([Ci.nsIURIFixup]),
};
function URIFixupInfo(originalInput = "") {
this._originalInput = originalInput;
}
URIFixupInfo.prototype = {
set consumer(consumer) {
this._consumer = consumer || null;
},
get consumer() {
return this._consumer || null;
},
set preferredURI(uri) {
this._preferredURI = uri;
},
get preferredURI() {
return this._preferredURI || null;
},
set fixedURI(uri) {
this._fixedURI = uri;
},
get fixedURI() {
return this._fixedURI || null;
},
set keywordProviderName(name) {
this._keywordProviderName = name;
},
get keywordProviderName() {
return this._keywordProviderName || "";
},
set keywordAsSent(keyword) {
this._keywordAsSent = keyword;
},
get keywordAsSent() {
return this._keywordAsSent || "";
},
set fixupChangedProtocol(changed) {
this._fixupChangedProtocol = changed;
},
get fixupChangedProtocol() {
return !!this._fixupChangedProtocol;
},
set fixupCreatedAlternateURI(changed) {
this._fixupCreatedAlternateURI = changed;
},
get fixupCreatedAlternateURI() {
return !!this._fixupCreatedAlternateURI;
},
set originalInput(input) {
this._originalInput = input;
},
get originalInput() {
return this._originalInput || "";
},
classID: Components.ID("{33d75835-722f-42c0-89cc-44f328e56a86}"),
QueryInterface: ChromeUtils.generateQI([Ci.nsIURIFixupInfo]),
};
// Helpers
function tryKeywordFixupForURIInfo(
uriString,
fixupInfo,
isPrivateContext,
postData
) {
try {
let keywordInfo = Services.uriFixup.keywordToURI(
uriString,
isPrivateContext,
postData
);
fixupInfo.keywordProviderName = keywordInfo.keywordProviderName;
fixupInfo.keywordAsSent = keywordInfo.keywordAsSent;
fixupInfo.preferredURI = keywordInfo.preferredURI;
} catch (ex) {}
}
function makeAlternateFixedURI(info) {
let uri = info.fixedURI;
if (
!alternateEnabled ||
// Code only works for http. Not for any other protocol including https!
!uri.schemeIs("http") ||
// Security - URLs with user / password info should NOT be fixed up
uri.userPass ||
// Don't fix up hosts with ports
uri.port != -1
) {
return false;
}
let oldHost = uri.host;
// Don't fix up 'localhost' because that's confusing:
if (oldHost == "localhost") {
return false;
}
let numDots = (oldHost.match(/\./g) || []).length;
// Get the prefix and suffix to stick onto the new hostname. By default these
// are www. & .com but they could be any other value, e.g. www. & .org
let prefix = Services.prefs.getCharPref(
"browser.fixup.alternate.prefix",
"www."
);
let suffix = Services.prefs.getCharPref(
"browser.fixup.alternate.suffix",
".com"
);
let newHost = "";
if (numDots == 0) {
newHost = prefix + oldHost + suffix;
} else if (numDots == 1) {
if (prefix && oldHost.toLowerCase() == prefix) {
newHost = oldHost + suffix;
} else if (suffix) {
newHost = prefix + oldHost;
}
}
if (!newHost) {
return false;
}
// Assign the new host string over the old one
try {
info.fixedURI = uri
.mutate()
.setHost(newHost)
.finalize();
} catch (ex) {
if (ex.result != Cr.NS_ERROR_MALFORMED_URI) {
throw ex;
}
return false;
}
return true;
}
/**
* Try to fixup a file URI.
* @param uriString The file URI to fix.
* @returns {nsIURI} a fixed uri or null.
* @note FileURIFixup only returns a URI if it has to add the file: protocol.
*/
function fileURIFixup(uriString) {
let attemptFixup = false;
if (AppConstants.platform == "win") {
// Check for "\"" in the url-string or just a drive (e.g. C:).
attemptFixup =
uriString.includes("\\") ||
(uriString.length == 2 && uriString.endsWith(":"));
} else {
// UNIX: Check if it starts with "/".
attemptFixup = uriString.startsWith("/");
}
if (attemptFixup) {
try {
// Test if this is a valid path by trying to create a local file
// object. The URL of that is returned if successful.
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(uriString);
return Services.io.newFileURI(file);
} catch (ex) {
// Not a file uri.
}
}
return null;
}
function fixupURIProtocol(uriString, fixupInfo) {
// Add http:// to front of url if it has no spec
//
// Should fix:
//
// no-scheme.com
// ftp.no-scheme.com
// ftp4.no-scheme.com
// no-scheme.com/query?foo=http://www.foo.com
// user:pass@no-scheme.com
//
let schemePos = uriString.indexOf("://");
if (schemePos == -1 || schemePos > uriString.search(/[:\/]/)) {
uriString = "http://" + uriString;
// TODO: This should only be set if this code runs and newURI succeeds
// below, but tests fail and some code may depend on this bug.
fixupInfo.fixupChangedProtocol = true;
}
try {
return Services.io.newURI(uriString);
} catch (ex) {
// We generated an invalid uri.
}
return null;
}
function keywordURIFixup(uriString, fixupInfo, isPrivateContext, postData) {
// These are keyword formatted strings
// "what is mozilla"
// "what is mozilla?"
// "docshell site:mozilla.org" - has no dot/colon in the first space-separated
// substring
// "?mozilla" - anything that begins with a question mark
// "?site:mozilla.org docshell"
// Things that have a quote before the first dot/colon
// "mozilla" - checked against a whitelist to see if it's a host or not
// ".mozilla", "mozilla." - ditto
// These are not keyword formatted strings
// "www.blah.com" - first space-separated substring contains a dot, doesn't
// start with "?" "www.blah.com stuff" "nonQualifiedHost:80" - first
// space-separated substring contains a colon, doesn't start with "?"
// "nonQualifiedHost:80 args"
// "nonQualifiedHost?"
// "nonQualifiedHost?args"
// "nonQualifiedHost?some args"
// "blah.com."
// Note: -1 is greater than any actual location
// in practice. So if we cast all locations to uint32_t, then a <
// b guarantees that either b is kNotFound and a is found, or both
// are found and a found before b.
// TODO: the cpp code used to assign -1 to an unsigned int, causing overflow.
// We should replace most of this with better js code.
const NOT_FOUND = Infinity;
let firstDotLoc = NOT_FOUND;
let lastDotLoc = NOT_FOUND;
let firstColonLoc = NOT_FOUND;
let firstQuoteLoc = NOT_FOUND;
let firstSpaceLoc = NOT_FOUND;
let firstQMarkLoc = NOT_FOUND;
let lastLSBracketLoc = NOT_FOUND;
let lastSlashLoc = NOT_FOUND;
let foundDots = 0;
let foundColons = 0;
let foundDigits = 0;
let foundRSBrackets = 0;
let looksLikeIpv6 = true;
let hasAsciiAlpha = false;
for (let i = 0, pos = 0; i < uriString.length; ++i, ++pos) {
let iter = uriString[i];
if (pos >= 1 && foundRSBrackets == 0) {
if (
!(
lastLSBracketLoc == 0 &&
(iter == ":" ||
iter == "." ||
iter == "]" ||
asciiHexRegex.test(iter))
)
) {
looksLikeIpv6 = false;
}
}
// If we're at the end of the string or this is the first slash,
// check if the thing before the slash looks like ipv4:
if (
(i == uriString.length - 1 ||
(lastSlashLoc == NOT_FOUND && iter == "/")) &&
// Need 2 or 3 dots + only digits
(foundDots == 2 || foundDots == 3) &&
// and they should be all that came before now:
(foundDots + foundDigits == pos ||
// or maybe there was also exactly 1 colon that came after the last
// dot, and the digits, dots and colon were all that came before now:
(foundColons == 1 &&
firstColonLoc > lastDotLoc &&
foundDots + foundDigits + foundColons == pos))
) {
// Hurray, we got ourselves some ipv4!
// At this point, there's no way we will do a keyword lookup, so just bail
// immediately:
return;
}
if (iter == ".") {
foundDots++;
lastDotLoc = pos;
if (firstDotLoc == NOT_FOUND) {
firstDotLoc = pos;
}
} else if (iter == ":") {
foundColons++;
if (firstColonLoc == NOT_FOUND) {
firstColonLoc = pos;
}
} else if (iter == " " && firstSpaceLoc == NOT_FOUND) {
firstSpaceLoc = pos;
} else if (iter == "?" && firstQMarkLoc == NOT_FOUND) {
firstQMarkLoc = pos;
} else if ((iter == "'" || iter == '"') && firstQuoteLoc == NOT_FOUND) {
firstQuoteLoc = pos;
} else if (iter == "[") {
lastLSBracketLoc = pos;
} else if (iter == "]") {
foundRSBrackets++;
} else if (iter == "/") {
lastSlashLoc = pos;
} else if (asciiAlphaRegex.test(iter)) {
hasAsciiAlpha = true;
} else if (asciiDigitRegex.test(iter)) {
foundDigits++;
}
}
if (lastLSBracketLoc > 0 || foundRSBrackets != 1) {
looksLikeIpv6 = false;
}
// If there are only colons and only hexadecimal characters ([a-z][0-9])
// enclosed in [], then don't do a keyword lookup
if (looksLikeIpv6) {
return;
}
let asciiHost = fixupInfo.fixedURI && fixupInfo.fixedURI.asciiHost;
let displayHost = fixupInfo.fixedURI && fixupInfo.fixedURI.displayHost;
// We do keyword lookups if a space or quote preceded the dot, colon
// or question mark (or if the latter is not found, or if the input starts
// with a question mark)
if (
((firstSpaceLoc < firstDotLoc || firstQuoteLoc < firstDotLoc) &&
(firstSpaceLoc < firstColonLoc || firstQuoteLoc < firstColonLoc) &&
(firstSpaceLoc < firstQMarkLoc || firstQuoteLoc < firstQMarkLoc)) ||
firstQMarkLoc == 0
) {
tryKeywordFixupForURIInfo(
fixupInfo.originalInput,
fixupInfo,
isPrivateContext,
postData
);
// ... or when the asciiHost is the same as displayHost and there are no
// characters from [a-z][A-Z]
} else if (
asciiHost &&
displayHost &&
!hasAsciiAlpha &&
asciiHost.toLowerCase() == displayHost.toLowerCase()
) {
if (!dnsFirstForSingleWords) {
tryKeywordFixupForURIInfo(
fixupInfo.originalInput,
fixupInfo,
isPrivateContext,
postData
);
}
// ... or if there is no question mark or colon, and there is either no
// dot, or exactly 1 and it is the first or last character of the input:
} else if (
(firstDotLoc == NOT_FOUND ||
(foundDots == 1 &&
(firstDotLoc == 0 || firstDotLoc == uriString.length - 1))) &&
firstColonLoc == NOT_FOUND &&
firstQMarkLoc == NOT_FOUND
) {
if (
asciiHost &&
Services.uriFixup.isDomainWhitelisted(asciiHost, firstDotLoc)
) {
return;
}
// ... unless there are no dots, and a slash, and alpha characters, and
// this is a valid host:
if (
firstDotLoc == NOT_FOUND &&
lastSlashLoc != NOT_FOUND &&
hasAsciiAlpha &&
asciiHost
) {
return;
}
// If we get here, we don't have a valid URI, or we did but the
// host is not whitelisted, so we do a keyword search *anyway*:
tryKeywordFixupForURIInfo(
fixupInfo.originalInput,
fixupInfo,
isPrivateContext,
postData
);
}
}
function extractScheme(uriString) {
let matches = uriString.match(possibleProtocolRegex);
return matches ? matches[1].replace("\t", "").toLowerCase() : "";
}

View File

@ -89,7 +89,6 @@ UNIFIED_SOURCES += [
'ChildProcessChannelListener.cpp',
'LoadContext.cpp',
'nsAboutRedirector.cpp',
'nsDefaultURIFixup.cpp',
'nsDocShell.cpp',
'nsDocShellEditorData.cpp',
'nsDocShellEnumerator.cpp',
@ -124,3 +123,7 @@ LOCAL_INCLUDES += [
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
CXXFLAGS += ['-Wno-error=shadow']
EXTRA_JS_MODULES += [
'URIFixup.jsm'
]

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSDEFAULTURIFIXUP_H
#define NSDEFAULTURIFIXUP_H
#include "nsIURIFixup.h"
class nsDefaultURIFixupInfo;
/* Header file */
class nsDefaultURIFixup : public nsIURIFixup {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURIFIXUP
nsDefaultURIFixup();
protected:
virtual ~nsDefaultURIFixup();
private:
/* additional members */
nsresult FileURIFixup(const nsACString& aStringURI, nsIURI** aURI);
nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aResult);
nsresult FixupURIProtocol(const nsACString& aIn,
nsDefaultURIFixupInfo* aFixupInfo, nsIURI** aURI);
nsresult KeywordURIFixup(const nsACString& aStringURI,
nsDefaultURIFixupInfo* aFixupInfo,
bool aIsPrivateContext, nsIInputStream** aPostData);
nsresult TryKeywordFixupForURIInfo(const nsACString& aStringURI,
nsDefaultURIFixupInfo* aFixupInfo,
bool aIsPrivateContext,
nsIInputStream** aPostData);
bool PossiblyHostPortUrl(const nsACString& aUrl);
bool MakeAlternateURI(nsCOMPtr<nsIURI>& aURI);
bool IsDomainWhitelisted(const nsACString& aAsciiHost,
const uint32_t aDotLoc);
};
class nsDefaultURIFixupInfo : public nsIURIFixupInfo {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURIFIXUPINFO
explicit nsDefaultURIFixupInfo(const nsACString& aOriginalInput);
friend class nsDefaultURIFixup;
protected:
virtual ~nsDefaultURIFixupInfo();
private:
nsCOMPtr<nsISupports> mConsumer;
nsCOMPtr<nsIURI> mPreferredURI;
nsCOMPtr<nsIURI> mFixedURI;
bool mFixupChangedProtocol;
bool mFixupCreatedAlternateURI;
nsString mKeywordProviderName;
nsString mKeywordAsSent;
nsCString mOriginalInput;
};
#endif

View File

@ -101,6 +101,7 @@
#include "nsIDocumentLoaderFactory.h"
#include "nsIDOMWindow.h"
#include "nsIEditingSession.h"
#include "nsIEffectiveTLDService.h"
#include "nsIExternalProtocolService.h"
#include "nsIFormPOSTActionChannel.h"
#include "nsIFrame.h"
@ -265,9 +266,6 @@ const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties";
const char kAppstringsBundleURL[] =
"chrome://global/locale/appstrings.properties";
// Global reference to the URI fixup service.
nsIURIFixup* nsDocShell::sURIFixup = nullptr;
static void FavorPerformanceHint(bool aPerfOverStarvation) {
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
if (appShell) {
@ -419,14 +417,6 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
mContentWindowID = nsContentUtils::GenerateWindowId();
}
if (gDocShellCount++ == 0) {
NS_ASSERTION(sURIFixup == nullptr,
"Huh, sURIFixup not null in first nsDocShell ctor!");
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
uriFixup.forget(&sURIFixup);
}
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p created\n", this));
#ifdef DEBUG
@ -456,10 +446,6 @@ nsDocShell::~nsDocShell() {
mContentViewer = nullptr;
}
if (--gDocShellCount == 0) {
NS_IF_RELEASE(sURIFixup);
}
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug, ("DOCSHELL %p destroyed\n", this));
#ifdef DEBUG
@ -3491,8 +3477,7 @@ nsresult nsDocShell::LoadURI(const nsAString& aURI,
RefPtr<nsDocShellLoadState> loadState;
nsresult rv = nsDocShellLoadState::CreateFromLoadURIOptions(
GetAsSupports(this), sURIFixup, aURI, aLoadURIOptions,
getter_AddRefs(loadState));
GetAsSupports(this), aURI, aLoadURIOptions, getter_AddRefs(loadState));
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
if (NS_ERROR_MALFORMED_URI == rv) {
@ -6000,6 +5985,45 @@ nsDocShell::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
return NS_OK;
}
already_AddRefed<nsIURIFixupInfo> nsDocShell::KeywordToURI(
const nsACString& aKeyword, bool aIsPrivateContext,
nsIInputStream** aPostData) {
nsCOMPtr<nsIURIFixupInfo> info;
if (XRE_IsContentProcess()) {
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
if (!contentChild) {
return nullptr;
}
info = do_CreateInstance("@mozilla.org/docshell/uri-fixup-info;1");
if (NS_WARN_IF(!info)) {
return nullptr;
}
RefPtr<nsIInputStream> postData;
RefPtr<nsIURI> uri;
nsAutoString providerName;
nsAutoCString keyword(aKeyword);
// TODO (Bug 1375244): This synchronous IPC messaging should be changed.
if (contentChild->SendKeywordToURI(keyword, aIsPrivateContext,
&providerName, &postData, &uri)) {
NS_ConvertUTF8toUTF16 keywordW(aKeyword);
info->SetKeywordAsSent(keywordW);
info->SetKeywordProviderName(providerName);
if (aPostData) {
postData.forget(aPostData);
}
info->SetPreferredURI(uri);
}
} else {
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
if (uriFixup) {
uriFixup->KeywordToURI(aKeyword, aIsPrivateContext, aPostData,
getter_AddRefs(info));
}
}
return info.forget();
}
nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
nsIChannel* aChannel, nsresult aStatus) {
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
@ -6175,7 +6199,8 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
return NS_OK;
}
if (sURIFixup) {
if ((aStatus == NS_ERROR_UNKNOWN_HOST || aStatus == NS_ERROR_NET_RESET) &&
((mLoadType == LOAD_NORMAL && isTopFrame) || mAllowKeywordFixup)) {
//
// Try and make an alternative URI from the old one
//
@ -6190,16 +6215,6 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
//
nsAutoString keywordProviderName, keywordAsSent;
if (aStatus == NS_ERROR_UNKNOWN_HOST && mAllowKeywordFixup) {
bool keywordsEnabled = Preferences::GetBool("keyword.enabled", false);
nsAutoCString host;
url->GetHost(host);
nsAutoCString scheme;
url->GetScheme(scheme);
int32_t dotLoc = host.FindChar('.');
// we should only perform a keyword search under the following
// conditions:
// (0) Pref keyword.enabled is true
@ -6212,51 +6227,66 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// Someone needs to clean up keywords in general so we can
// determine on a per url basis if we want keywords
// enabled...this is just a bandaid...
if (keywordsEnabled && !scheme.IsEmpty() &&
(scheme.Find("http") != 0)) {
keywordsEnabled = false;
}
if (keywordsEnabled && (kNotFound == dotLoc)) {
nsCOMPtr<nsIURIFixupInfo> info;
// only send non-qualified hosts to the keyword server
if (!mOriginalUriString.IsEmpty()) {
sURIFixup->KeywordToURI(mOriginalUriString, UsePrivateBrowsing(),
getter_AddRefs(newPostData),
getter_AddRefs(info));
nsAutoCString scheme;
Unused << url->GetScheme(scheme);
if (Preferences::GetBool("keyword.enabled", false) &&
StringBeginsWith(scheme, NS_LITERAL_CSTRING("http"))) {
bool attemptFixup = false;
nsAutoCString host;
Unused << url->GetHost(host);
if (host.FindChar('.') == kNotFound) {
attemptFixup = true;
} else {
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsAutoCString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv && NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) && isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host))) {
sURIFixup->KeywordToURI(utf8Host, UsePrivateBrowsing(),
getter_AddRefs(newPostData),
getter_AddRefs(info));
} else {
sURIFixup->KeywordToURI(host, UsePrivateBrowsing(),
getter_AddRefs(newPostData),
getter_AddRefs(info));
// For domains with dots, we check the public suffix validity.
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (tldService) {
nsAutoCString suffix;
attemptFixup =
NS_SUCCEEDED(tldService->GetKnownPublicSuffix(url, suffix)) &&
suffix.IsEmpty();
}
}
info->GetPreferredURI(getter_AddRefs(newURI));
if (newURI) {
info->GetKeywordAsSent(keywordAsSent);
info->GetKeywordProviderName(keywordProviderName);
if (attemptFixup) {
nsCOMPtr<nsIURIFixupInfo> info;
// only send non-qualified hosts to the keyword server
if (!mOriginalUriString.IsEmpty()) {
info = KeywordToURI(mOriginalUriString, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
} else {
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsAutoCString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv && NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) &&
isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host))) {
info = KeywordToURI(utf8Host, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
} else {
info = KeywordToURI(host, UsePrivateBrowsing(),
getter_AddRefs(newPostData));
}
}
if (info) {
info->GetPreferredURI(getter_AddRefs(newURI));
if (newURI) {
info->GetKeywordAsSent(keywordAsSent);
info->GetKeywordProviderName(keywordProviderName);
}
}
}
} // end keywordsEnabled
}
}
//
@ -6297,9 +6327,12 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
newPostData = nullptr;
keywordProviderName.Truncate();
keywordAsSent.Truncate();
sURIFixup->CreateFixupURI(
oldSpec, nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
getter_AddRefs(newPostData), getter_AddRefs(newURI));
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
if (uriFixup) {
uriFixup->CreateFixupURI(
oldSpec, nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
getter_AddRefs(newPostData), getter_AddRefs(newURI));
}
}
}

View File

@ -82,6 +82,7 @@ class nsISecureBrowserUI;
class nsISHistory;
class nsIStringBundle;
class nsIURIFixup;
class nsIURIFixupInfo;
class nsIURILoader;
class nsIWebBrowserFind;
class nsIWidget;
@ -835,6 +836,10 @@ class nsDocShell final : public nsDocLoader,
nsIChannel* aChannel, nsIURI* aURI, uint32_t aChannelRedirectFlags,
const nsTArray<mozilla::net::DocumentChannelRedirect>& aRedirects);
already_AddRefed<nsIURIFixupInfo> KeywordToURI(const nsACString& aKeyword,
bool aIsPrivateContext,
nsIInputStream** aPostData);
// Sets the current document's current state object to the given SHEntry's
// state object. The current state object is eventually given to the page
// in the PopState event.
@ -1097,10 +1102,8 @@ class nsDocShell final : public nsDocLoader,
SameDocumentNavigationState& aState);
private: // data members
static nsIURIFixup* sURIFixup;
#ifdef DEBUG
// We're counting the number of |nsDocShells| to help find leaks
// We're counting the number of |nsDocShells| to help find leaks
static unsigned long gNumberOfDocShells;
#endif /* DEBUG */

View File

@ -13,15 +13,20 @@
#include "nsIChannel.h"
#include "ReferrerInfo.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/OriginAttributes.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/PContent.h"
// Global reference to the URI fixup service.
static mozilla::StaticRefPtr<nsIURIFixup> sURIFixup;
nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
: mURI(aURI),
mResultPrincipalURIIsSome(false),
@ -120,7 +125,7 @@ nsresult nsDocShellLoadState::CreateFromPendingChannel(
}
nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
nsISupports* aConsumer, nsIURIFixup* aURIFixup, const nsAString& aURI,
nsISupports* aConsumer, const nsAString& aURI,
const LoadURIOptions& aLoadURIOptions, nsDocShellLoadState** aResult) {
uint32_t loadFlags = aLoadURIOptions.mLoadFlags;
@ -139,10 +144,28 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
// Just create a URI and see what happens...
rv = NS_NewURI(getter_AddRefs(uri), uriString);
bool fixup = true;
if (NS_SUCCEEDED(rv) && uri &&
(uri->SchemeIs("about") || uri->SchemeIs("chrome"))) {
// Avoid third party fixup as a performance optimization.
loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
fixup = false;
} else if (!sURIFixup) {
nsCOMPtr<nsIURIFixup> uriFixup = components::URIFixup::Service();
if (uriFixup) {
sURIFixup = uriFixup;
ClearOnShutdown(&sURIFixup);
} else {
fixup = false;
}
}
nsCOMPtr<nsIURIFixupInfo> fixupInfo;
if (aURIFixup) {
if (fixup) {
uint32_t fixupFlags;
rv = aURIFixup->WebNavigationFlagsToFixupFlags(uriString, loadFlags,
rv = sURIFixup->WebNavigationFlagsToFixupFlags(uriString, loadFlags,
&fixupFlags);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
@ -164,7 +187,7 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
fixupFlags |= nsIURIFixup::FIXUP_FLAG_PRIVATE_CONTEXT;
}
nsCOMPtr<nsIInputStream> fixupStream;
rv = aURIFixup->GetFixupURIInfo(uriString, fixupFlags,
rv = sURIFixup->GetFixupURIInfo(uriString, fixupFlags,
getter_AddRefs(fixupStream),
getter_AddRefs(fixupInfo));
@ -180,17 +203,14 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
postData = fixupStream;
}
if (loadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
if (fixupInfo &&
loadFlags & nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
if (serv) {
serv->NotifyObservers(fixupInfo, "keyword-uri-fixup",
PromiseFlatString(aURI).get());
}
}
} else {
// No fixup service so just create a URI and see what happens...
rv = NS_NewURI(getter_AddRefs(uri), uriString);
loadFlags &= ~nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
}
if (rv == NS_ERROR_MALFORMED_URI) {

View File

@ -44,7 +44,7 @@ class nsDocShellLoadState final {
nsDocShellLoadState** aResult);
static nsresult CreateFromLoadURIOptions(
nsISupports* aConsumer, nsIURIFixup* aURIFixup, const nsAString& aURI,
nsISupports* aConsumer, const nsAString& aURI,
const mozilla::dom::LoadURIOptions& aLoadURIOptions,
nsDocShellLoadState** aResult);

View File

@ -26,31 +26,31 @@ interface nsIURIFixupInfo : nsISupports
* the input was invalid as a URI and FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
* was not passed)
*/
readonly attribute nsIURI preferredURI;
attribute nsIURI preferredURI;
/**
* The fixed-up original input, *never* using a keyword search.
* (might be null if the original input was not recoverable as
* a URL, e.g. "foo bar"!)
*/
readonly attribute nsIURI fixedURI;
attribute nsIURI fixedURI;
/**
* The name of the keyword search provider used to provide a keyword search;
* empty string if no keyword search was done.
*/
readonly attribute AString keywordProviderName;
attribute AString keywordProviderName;
/**
* The keyword as used for the search (post trimming etc.)
* empty string if no keyword search was done.
*/
readonly attribute AString keywordAsSent;
attribute AString keywordAsSent;
/**
* Whether we changed the protocol instead of using one from the input as-is.
*/
readonly attribute boolean fixupChangedProtocol;
attribute boolean fixupChangedProtocol;
/**
* Whether we created an alternative URI. We might have added a prefix and/or
@ -58,12 +58,12 @@ interface nsIURIFixupInfo : nsISupports
* browser.fixup.alternate.prefix and .suffix prefs, with the defaults being
* "www." and ".com", respectively.
*/
readonly attribute boolean fixupCreatedAlternateURI;
attribute boolean fixupCreatedAlternateURI;
/**
* The original input
*/
readonly attribute AUTF8String originalInput;
attribute AUTF8String originalInput;
};

View File

@ -53,10 +53,16 @@ Classes = [
},
{
'name': 'URIFixup',
'cid': '{214c48a0-b57f-11d4-959c-0020183bf181}',
'contract_ids': ['@mozilla.org/docshell/urifixup;1'],
'type': 'nsDefaultURIFixup',
'headers': ['/docshell/base/nsDefaultURIFixup.h'],
'cid': '{c6cf88b7-452e-47eb-bdc9-86e3561648ef}',
'contract_ids': ['@mozilla.org/docshell/uri-fixup;1'],
'jsm': 'resource://gre/modules/URIFixup.jsm',
'constructor': 'URIFixup',
},
{
'cid': '{33d75835-722f-42c0-89cc-44f328e56a86}',
'contract_ids': ['@mozilla.org/docshell/uri-fixup-info;1'],
'jsm': 'resource://gre/modules/URIFixup.jsm',
'constructor': 'URIFixupInfo',
},
{
'cid': '{a7f800e0-4306-11d4-98d0-001083010e9b}',

View File

@ -46,6 +46,10 @@ var flagInputs = [
}
*/
var testcases = [
{
input: "about:home",
fixedURI: "about:home",
},
{
input: "http://www.mozilla.org",
fixedURI: "http://www.mozilla.org/",
@ -188,13 +192,11 @@ var testcases = [
{
input: "[::1]",
fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/",
protocolChange: true,
},
{
input: "[::1]/",
fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/",
protocolChange: true,
},
{
@ -215,19 +217,16 @@ var testcases = [
{
input: "[fe80:cd00:0:cde:1257:0:211e:729c]",
fixedURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
alternateURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
protocolChange: true,
},
{
input: "[64:ff9b::8.8.8.8]",
fixedURI: "http://[64:ff9b::808:808]/",
alternateURI: "http://[64:ff9b::808:808]/",
protocolChange: true,
},
{
input: "[64:ff9b::8.8.8.8]/~moz",
fixedURI: "http://[64:ff9b::808:808]/~moz",
alternateURI: "http://[64:ff9b::808:808]/~moz",
protocolChange: true,
},
{

View File

@ -905,17 +905,6 @@
value: @IS_NOT_MOZILLA_OFFICIAL@
mirror: always
# Fix up common scheme typos?
- name: browser.fixup.typo.scheme
type: bool
value: true
mirror: always
- name: browser.fixup.dns_first_for_single_words
type: bool
value: false
mirror: always
# Render animations and videos as a solid color
- name: browser.measurement.render_anims_and_video_solid
type: RelaxedAtomicBool
@ -4613,15 +4602,6 @@
#endif
mirror: always
#---------------------------------------------------------------------------
# Prefs starting with "keyword."
#---------------------------------------------------------------------------
- name: keyword.enabled
type: bool
value: false
mirror: always
#---------------------------------------------------------------------------
# Prefs starting with "layers."
#---------------------------------------------------------------------------

View File

@ -54,7 +54,6 @@ pref_groups = [
'image',
'intl',
'javascript',
'keyword',
'layers',
'layout',
'mathml',

View File

@ -853,18 +853,15 @@ var BrowserUtils = {
trimURL(aURL) {
// This function must not modify the given URL such that calling
// nsIURIFixup::createFixupURI with the result will produce a different URI.
let url = this.removeSingleTrailingSlashFromURL(aURL);
// remove http://
if (!url.startsWith("http://")) {
return url;
}
let urlWithoutProtocol = url.substring(7);
// It doesn't really matter which search engine is used here, thus it's ok
// to ignore whether we are in a private context. The keyword lookup is only
// used to differentiate between whitelisted and not whitelisted hosts.
// to ignore whether we are in a private context. The keyword lookup will
// also distinguish between whitelisted and not whitelisted hosts.
// For example, if "someword" is not a whitelisted host, setting the urlbar
// value to "http://someword" should not trim it, because otherwise
// confirming the urlbar value would end up searching for "someword".

View File

@ -130,7 +130,7 @@ var initTable = {
"nsIDOMRequestService",
],
focus: ["@mozilla.org/focus-manager;1", "nsIFocusManager"],
uriFixup: ["@mozilla.org/docshell/urifixup;1", "nsIURIFixup"],
uriFixup: ["@mozilla.org/docshell/uri-fixup;1", "nsIURIFixup"],
blocklist: ["@mozilla.org/extensions/blocklist;1"],
netUtils: ["@mozilla.org/network/util;1", "nsINetUtil"],
loadContextInfo: [

View File

@ -52,7 +52,7 @@ service('HistoryService', 'mozilla::IHistory',
service('ThirdPartyUtil', 'mozIThirdPartyUtil',
"@mozilla.org/thirdpartyutil;1")
service('URIFixup', 'nsIURIFixup',
"@mozilla.org/docshell/urifixup;1")
"@mozilla.org/docshell/uri-fixup;1")
service('Bits', 'nsIBits',
"@mozilla.org/bits;1")
# NB: this should also expose nsIXULAppInfo, as does Services.jsm.