From d77a8d39c151e6179748a5c05fbdad2db9594bab Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Wed, 2 Dec 2015 16:13:18 -0800 Subject: [PATCH] Bug 1216986 - Fix usage of nsIURI.host in password manager and prompt code to support IPv6. r=dolske,liuche,kanru --HG-- extra : commitid : zwoW6hAPKy extra : rebase_source : 183b3f29af92860fbe232427e9e8f1cdd7116707 --- .../BrowserElementPromptService.jsm | 18 +++-------- .../components/LoginManagerPrompter.js | 32 ------------------- mobile/android/components/PromptService.js | 16 +++------- .../passwordmgr/LoginManagerContent.jsm | 25 ++++----------- .../passwordmgr/nsLoginManagerPrompter.js | 20 ++---------- .../test/unit/test_getPasswordOrigin.js | 28 ++++++++++++++++ .../passwordmgr/test/unit/xpcshell.ini | 1 + toolkit/components/prompts/src/nsPrompter.js | 18 +++-------- 8 files changed, 52 insertions(+), 106 deletions(-) create mode 100644 toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js diff --git a/dom/browser-element/BrowserElementPromptService.jsm b/dom/browser-element/BrowserElementPromptService.jsm index 7686ea3ca88b..a70ee28f8920 100644 --- a/dom/browser-element/BrowserElementPromptService.jsm +++ b/dom/browser-element/BrowserElementPromptService.jsm @@ -429,20 +429,12 @@ BrowserElementAuthPrompt.prototype = { return [hostname, realm]; }, + /** + * Strip out things like userPass and path for display. + */ _getFormattedHostname : function(uri) { - let scheme = uri.scheme; - let hostname = scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - let port = uri.port; - if (port != -1) { - let handler = Services.io.getProtocolHandler(scheme); - if (port != handler.defaultPort) - hostname += ":" + port; - } - return hostname; - } + return uri.scheme + "://" + uri.hostPort; + }, }; diff --git a/mobile/android/components/LoginManagerPrompter.js b/mobile/android/components/LoginManagerPrompter.js index 1eddcb424e24..70fa3687118e 100644 --- a/mobile/android/components/LoginManagerPrompter.js +++ b/mobile/android/components/LoginManagerPrompter.js @@ -400,38 +400,6 @@ LoginManagerPrompter.prototype = { } return username.replace(/['"]/g, ""); }, - - /* - * _getFormattedHostname - * - * The aURI parameter may either be a string uri, or an nsIURI instance. - * - * Returns the hostname to use in a nsILoginInfo object (for example, - * "http://example.com"). - */ - _getFormattedHostname : function (aURI) { - var uri; - if (aURI instanceof Ci.nsIURI) { - uri = aURI; - } else { - uri = Services.io.newURI(aURI, null, null); - } - var scheme = uri.scheme; - - var hostname = scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - let port = uri.port; - if (port != -1) { - var handler = Services.io.getProtocolHandler(scheme); - if (port != handler.defaultPort) - hostname += ":" + port; - } - - return hostname; - }, - }; // end of LoginManagerPrompter implementation diff --git a/mobile/android/components/PromptService.js b/mobile/android/components/PromptService.js index c9b5c4a3a466..2a2c3d29338d 100644 --- a/mobile/android/components/PromptService.js +++ b/mobile/android/components/PromptService.js @@ -798,19 +798,11 @@ var PromptUtils = { aAuthInfo.password = password; }, + /** + * Strip out things like userPass and path for display. + */ getFormattedHostname : function pu_getFormattedHostname(uri) { - let scheme = uri.scheme; - let hostname = scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - let port = uri.port; - if (port != -1) { - let handler = Services.io.getProtocolHandler(scheme); - if (port != handler.defaultPort) - hostname += ":" + port; - } - return hostname; + return uri.scheme + "://" + uri.hostPort; }, fireDialogEvent: function(aDomWin, aEventName) { diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index 3b81a9a37170..75fc97cf6a39 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -1149,41 +1149,30 @@ var LoginManagerContent = { }; var LoginUtils = { - /* - * _getPasswordOrigin - * + /** * Get the parts of the URL we want for identification. + * Strip out things like the userPass portion */ - _getPasswordOrigin : function (uriString, allowJS) { + _getPasswordOrigin(uriString, allowJS) { var realm = ""; try { var uri = Services.io.newURI(uriString, null, null); if (allowJS && uri.scheme == "javascript") - return "javascript:" - - realm = uri.scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - var port = uri.port; - if (port != -1) { - var handler = Services.io.getProtocolHandler(uri.scheme); - if (port != handler.defaultPort) - realm += ":" + port; - } + return "javascript:"; + realm = uri.scheme + "://" + uri.hostPort; } 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); + log("Couldn't parse origin for", uriString, e); realm = null; } return realm; }, - _getActionOrigin : function (form) { + _getActionOrigin(form) { var uriString = form.action; // A blank or missing action submits to where it came from. diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js index 351650c8b8a8..eb534443e80a 100644 --- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js +++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js @@ -1567,35 +1567,21 @@ LoginManagerPrompter.prototype = { }, - /* - * _getFormattedHostname - * + /** * The aURI parameter may either be a string uri, or an nsIURI instance. * * Returns the hostname to use in a nsILoginInfo object (for example, * "http://example.com"). */ _getFormattedHostname : function (aURI) { - var uri; + let uri; if (aURI instanceof Ci.nsIURI) { uri = aURI; } else { uri = Services.io.newURI(aURI, null, null); } - var scheme = uri.scheme; - var hostname = scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - var port = uri.port; - if (port != -1) { - var handler = Services.io.getProtocolHandler(scheme); - if (port != handler.defaultPort) - hostname += ":" + port; - } - - return hostname; + return uri.scheme + "://" + uri.hostPort; }, diff --git a/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js b/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js new file mode 100644 index 000000000000..f2773ec6246a --- /dev/null +++ b/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js @@ -0,0 +1,28 @@ +/* + * Test for LoginUtils._getPasswordOrigin + */ + +"use strict"; + +const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm"); +const TESTCASES = [ + ["javascript:void(0);", null], + ["javascript:void(0);", "javascript:", true], + ["chrome://MyAccount", null], + ["data:text/html,example", null], + ["http://username:password@example.com:80/foo?bar=baz#fragment", "http://example.com", true], + ["http://127.0.0.1:80/foo", "http://127.0.0.1"], + ["http://[::1]:80/foo", "http://[::1]"], + ["http://example.com:8080/foo", "http://example.com:8080"], + ["http://127.0.0.1:8080/foo", "http://127.0.0.1:8080", true], + ["http://[::1]:8080/foo", "http://[::1]:8080"], + ["https://example.com:443/foo", "https://example.com"], + ["https://[::1]:443/foo", "https://[::1]"], + ["https://[::1]:8443/foo", "https://[::1]:8443"], + ["ftp://username:password@[::1]:2121/foo", "ftp://[::1]:2121"], +]; + +for (let [input, expected, allowJS] of TESTCASES) { + let actual = LMCBackstagePass.LoginUtils._getPasswordOrigin(input, allowJS); + Assert.strictEqual(actual, expected, "Checking: " + input); +} diff --git a/toolkit/components/passwordmgr/test/unit/xpcshell.ini b/toolkit/components/passwordmgr/test/unit/xpcshell.ini index 365f0df4a471..f4d00ac0f0e6 100644 --- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini +++ b/toolkit/components/passwordmgr/test/unit/xpcshell.ini @@ -22,6 +22,7 @@ run-if = buildapp == "browser" [test_disabled_hosts.js] [test_getFormFields.js] [test_getPasswordFields.js] +[test_getPasswordOrigin.js] [test_legacy_empty_formSubmitURL.js] [test_legacy_validation.js] [test_logins_change.js] diff --git a/toolkit/components/prompts/src/nsPrompter.js b/toolkit/components/prompts/src/nsPrompter.js index 4d4ecaa998c8..8ba1ea0f88ea 100644 --- a/toolkit/components/prompts/src/nsPrompter.js +++ b/toolkit/components/prompts/src/nsPrompter.js @@ -204,21 +204,11 @@ var PromptUtilsTemp = { authInfo.password = password; }, - // Copied from login manager + /** + * Strip out things like userPass and path for display. + */ getFormattedHostname : function (uri) { - let scheme = uri.scheme; - let hostname = scheme + "://" + uri.host; - - // If the URI explicitly specified a port, only include it when - // it's not the default. (We never want "http://foo.com:80") - let port = uri.port; - if (port != -1) { - let handler = Services.io.getProtocolHandler(scheme); - if (port != handler.defaultPort) - hostname += ":" + port; - } - - return hostname; + return uri.scheme + "://" + uri.hostPort; }, // Copied from login manager