Bug 1400023 - Switch logins handling to use "display" URIs. r?mattn
Since the pref flip in
bug 1380617, the default nsUri attributes have been returning punycode for IDN-based domain names, so we need to switch to using the "display"-prefixed variants as a simple fix to
- preserve compatibility with previously stored logins
- pretty-print unicode domains in the login manager UI instead of showing punycode
This patch is more or less a straight (DXR-)search and replace and has hopefully caught all relevant instance of nsUri access related to logins.
For test_disabled_hosts, we're basically reverting
bug 1380617, since the login service will now once again return IDN domains in Unicode where allowed.
MozReview-Commit-ID: 5SvW0MuTrGu
--- a/mobile/android/chrome/content/PermissionsHelper.js
+++ b/mobile/android/chrome/content/PermissionsHelper.js
@@ -139,21 +139,21 @@ var PermissionsHelper = {
* @return A permission value defined in nsIPermissionManager.
*/
getPermission: function getPermission(aURI, aType) {
// Password saving isn't a nsIPermissionManager permission type, so handle
// it seperately.
if (aType == "password") {
// By default, login saving is enabled, so if it is disabled, the
// user selected the never remember option
- if (!Services.logins.getLoginSavingEnabled(aURI.prePath))
+ if (!Services.logins.getLoginSavingEnabled(aURI.displayPrePath))
return Services.perms.DENY_ACTION;
// Check to see if the user ever actually saved a login
- if (Services.logins.countLogins(aURI.prePath, "", ""))
+ if (Services.logins.countLogins(aURI.displayPrePath, "", ""))
return Services.perms.ALLOW_ACTION;
return Services.perms.UNKNOWN_ACTION;
}
// Geolocation consumers use testExactPermission
if (aType == "geolocation")
return Services.perms.testExactPermission(aURI, aType);
@@ -168,22 +168,22 @@ var PermissionsHelper = {
* The permission type string stored in permission manager.
* e.g. "geolocation", "indexedDB", "popup"
*/
clearPermission: function clearPermission(aURI, aType, aContext) {
// Password saving isn't a nsIPermissionManager permission type, so handle
// it seperately.
if (aType == "password") {
// Get rid of exisiting stored logings
- let logins = Services.logins.findLogins({}, aURI.prePath, "", "");
+ let logins = Services.logins.findLogins({}, aURI.displayPrePath, "", "");
for (let i = 0; i < logins.length; i++) {
Services.logins.removeLogin(logins[i]);
}
// Re-set login saving to enabled
- Services.logins.setLoginSavingEnabled(aURI.prePath, true);
+ Services.logins.setLoginSavingEnabled(aURI.displayPrePath, true);
} else {
Services.perms.remove(aURI, aType);
// Clear content prefs set in ContentPermissionPrompt.js
Cc["@mozilla.org/content-pref/service;1"]
.getService(Ci.nsIContentPrefService2)
.removeByDomainAndName(aURI.spec, aType + ".request.remember", aContext);
}
}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -4124,17 +4124,17 @@ Tab.prototype = {
WebsiteMetadata.parseAsynchronously(this.browser.contentDocument);
}
break;
}
case "DOMFormHasPassword": {
// Send logins for this hostname to Java.
- let hostname = aEvent.target.baseURIObject.prePath;
+ let hostname = aEvent.target.baseURIObject.displayPrePath;
let foundLogins = Services.logins.findLogins({}, hostname, "", "");
if (foundLogins.length > 0) {
let displayHost = IdentityHandler.getEffectiveHost();
let title = { text: displayHost, resource: hostname };
let selectObj = { title: title, logins: foundLogins };
GlobalEventDispatcher.sendRequest({
type: "Doorhanger:Logins",
data: selectObj
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -79,17 +79,17 @@ var observer = {
// nsIWebProgressListener
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
// Only handle pushState/replaceState here.
if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) ||
!(aWebProgress.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE)) {
return;
}
- log("onLocationChange handled:", aLocation.spec, aWebProgress.DOMWindow.document);
+ log("onLocationChange handled:", aLocation.displaySpec, aWebProgress.DOMWindow.document);
LoginManagerContent._onNavigation(aWebProgress.DOMWindow.document);
},
onStateChange(aWebProgress, aRequest, aState, aStatus) {
if (!(aState & Ci.nsIWebProgressListener.STATE_START)) {
return;
}
@@ -1382,17 +1382,17 @@ var LoginUtils = {
var realm = "";
try {
var uri = Services.io.newURI(uriString);
if (allowJS && uri.scheme == "javascript")
return "javascript:";
// Build this manually instead of using prePath to avoid including the userPass portion.
- realm = uri.scheme + "://" + uri.hostPort;
+ realm = uri.scheme + "://" + uri.displayHostPort;
} catch (e) {
// bug 159484 - disallow url types that don't support a hostPort.
// (although we handle "javascript:..." as a special case above.)
log("Couldn't parse origin for", uriString, e);
realm = null;
}
return realm;
--- a/toolkit/components/passwordmgr/LoginManagerContextMenu.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContextMenu.jsm
@@ -88,25 +88,25 @@ var LoginManagerContextMenu = {
* URI object with the hostname of the logins we want to find.
* This isn't the same as the browser's top-level document URI
* when subframes are involved.
*
* @returns {nsILoginInfo[]} a login list
*/
_findLogins(documentURI) {
let searchParams = {
- hostname: documentURI.prePath,
+ hostname: documentURI.displayPrePath,
schemeUpgrades: LoginHelper.schemeUpgrades,
};
let logins = LoginHelper.searchLoginsWithObject(searchParams);
let resolveBy = [
"scheme",
"timePasswordChanged",
];
- logins = LoginHelper.dedupeLogins(logins, ["username", "password"], resolveBy, documentURI.prePath);
+ logins = LoginHelper.dedupeLogins(logins, ["username", "password"], resolveBy, documentURI.displayPrePath);
// Sort logins in alphabetical order and by date.
logins.sort((loginA, loginB) => {
// Sort alphabetically
let result = loginA.username.localeCompare(loginB.username);
if (result) {
// Forces empty logins to be at the end
if (!loginA.username) {
@@ -157,17 +157,17 @@ var LoginManagerContextMenu = {
* @param {nsIURI} documentURI
* URI of the document owning the form we want to fill.
* This isn't the same as the browser's top-level
* document URI when subframes are involved.
*/
_fillTargetField(login, inputElement, browser, documentURI) {
LoginManagerParent.fillForm({
browser,
- loginFormOrigin: documentURI.prePath,
+ loginFormOrigin: documentURI.displayPrePath,
login,
inputElement,
}).catch(Cu.reportError);
},
/**
* @param {string} key
* The localized string key
--- a/toolkit/components/passwordmgr/nsLoginManager.js
+++ b/toolkit/components/passwordmgr/nsLoginManager.js
@@ -357,17 +357,17 @@ LoginManager.prototype = {
log.debug("Getting a list of all disabled origins");
let disabledHosts = [];
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
let perm = enumerator.getNext();
if (perm.type == PERMISSION_SAVE_LOGINS && perm.capability == Services.perms.DENY_ACTION) {
- disabledHosts.push(perm.principal.URI.prePath);
+ disabledHosts.push(perm.principal.URI.displayPrePath);
}
}
if (count)
count.value = disabledHosts.length; // needed for XPCOM
log.debug("getAllDisabledHosts: returning", disabledHosts.length, "disabled hosts.");
return disabledHosts;
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -1573,17 +1573,17 @@ LoginManagerPrompter.prototype = {
_getFormattedHostname(aURI) {
let uri;
if (aURI instanceof Ci.nsIURI) {
uri = aURI;
} else {
uri = Services.io.newURI(aURI);
}
- return uri.scheme + "://" + uri.hostPort;
+ return uri.scheme + "://" + uri.displayHostPort;
},
/**
* Converts a login's hostname field (a URL) to a short string for
* prompting purposes. Eg, "http://foo.com" --> "foo.com", or
* "ftp://www.site.co.uk" --> "site.co.uk".
*/
--- a/toolkit/components/passwordmgr/storage-mozStorage.js
+++ b/toolkit/components/passwordmgr/storage-mozStorage.js
@@ -462,17 +462,17 @@ LoginManagerStorage_mozStorage.prototype
if (value != null) {
condition += `${field} = :${field}`;
params[field] = value;
let valueURI;
try {
if (aOptions.schemeUpgrades && (valueURI = Services.io.newURI(value)) &&
valueURI.scheme == "https") {
condition += ` OR ${field} = :http${field}`;
- params["http" + field] = "http://" + valueURI.hostPort;
+ params["http" + field] = "http://" + valueURI.displayHostPort;
}
} catch (ex) {
// newURI will throw for some values (e.g. chrome://FirefoxAccounts)
// but those URLs wouldn't support upgrades anyways.
}
break;
}
// Fall through
--- a/toolkit/components/passwordmgr/test/unit/test_disabled_hosts.js
+++ b/toolkit/components/passwordmgr/test/unit/test_disabled_hosts.js
@@ -149,26 +149,26 @@ add_task(async function test_storage_set
let hostname = "http://大.net";
let encoding = "http://xn--pss.net";
// Test adding disabled host with nonascii URL (http://大.net).
Services.logins.setLoginSavingEnabled(hostname, false);
await LoginTestUtils.reloadData();
Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false);
Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false);
- LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [encoding]);
+ LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [hostname]);
LoginTestUtils.clearData();
// Test adding disabled host with IDN ("http://xn--pss.net").
Services.logins.setLoginSavingEnabled(encoding, false);
await LoginTestUtils.reloadData();
Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false);
Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false);
- LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [encoding]);
+ LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [hostname]);
LoginTestUtils.clearData();
});
/**
* Tests storing disabled hosts with non-ASCII characters where IDN is not supported.
*/
add_task(async function test_storage_setLoginSavingEnabled_nonascii_IDN_not_supported()