Bug 472824 promptPassword should unescape user names before use. r=dolkse,sr=mconnor
authorMark Banner <bugzilla@standard8.plus.com>
Thu, 15 Jan 2009 13:16:34 +0000
changeset 23743 5542884b9bdc8c0f14ecafd788628098d366bd45
parent 23742 789cb02b7399d6812573eed17fc3869817257866
child 23744 e30f1765a42c06c8b7ad376facdb09e30f4cbe0f
push id4695
push userbugzilla@standard8.plus.com
push dateThu, 15 Jan 2009 13:17:22 +0000
treeherdermozilla-central@5542884b9bdc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolkse, mconnor
bugs472824
milestone1.9.2a1pre
Bug 472824 promptPassword should unescape user names before use. r=dolkse,sr=mconnor
netwerk/base/public/nsIAuthPrompt.idl
toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js
toolkit/components/passwordmgr/test/test_prompt.html
--- a/netwerk/base/public/nsIAuthPrompt.idl
+++ b/netwerk/base/public/nsIAuthPrompt.idl
@@ -95,16 +95,18 @@ interface nsIAuthPrompt : nsISupports
      * @param  dialogText    The title for the dialog.
      * @param  text          The text to display in the dialog.
      * @param  passwordRealm The "realm" the password belongs to: e.g.
      *                       ldap://localhost/dc=test. If a username is
      *                       specified (http://user@site.com) it will be used
      *                       when matching existing logins or saving new ones.
      *                       If no username is specified, only password-only
      *                       logins will be matched or saved.
+     *                       Note: if a username is specified, the username
+     *                       should be escaped.
      * @param  savePassword  One of the SAVE_PASSWORD_* options above.
      * @param  pwd           The password entered by the user if OK was
      *                       selected.
      * @return true for OK, false for Cancel
      */
     boolean promptPassword(in wstring dialogTitle,
                            in wstring text,
                            in wstring passwordRealm,
--- a/toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/src/nsLoginManagerPrompter.js
@@ -349,16 +349,18 @@ LoginManagerPrompter.prototype = {
 
         if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
 
         var checkBox = { value : false };
         var checkBoxLabel = null;
         var [hostname, realm, username] = this._getRealmInfo(aPasswordRealm);
 
+        username = decodeURIComponent(username);
+
         // If hostname is null, we can't save this login.
         if (hostname && !this._inPrivateBrowsing) {
           var canRememberLogin = (aSavePassword ==
                                   Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
                                  this._pwmgr.getLoginSavingEnabled(hostname);
   
           // if checkBoxLabel is null, the checkbox won't be shown at all.
           if (canRememberLogin)
--- a/toolkit/components/passwordmgr/test/test_prompt.html
+++ b/toolkit/components/passwordmgr/test/test_prompt.html
@@ -18,64 +18,82 @@ Login Manager test: username/password pr
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Login Manager: username / password prompts. **/
 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
 
-var pwmgr, tmplogin, login1, login2A, login2B, login3A, login3B, login4;
+var pwmgr, tmplogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4;
 
 function initLogins() {
   pwmgr = Cc["@mozilla.org/login-manager;1"].
           getService(Ci.nsILoginManager);
 
   tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
              createInstance(Ci.nsILoginInfo);
 
   login1  = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
   login2A = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
   login2B = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
+  login2C = Cc["@mozilla.org/login-manager/loginInfo;1"].
+            createInstance(Ci.nsILoginInfo);
+  login2D = Cc["@mozilla.org/login-manager/loginInfo;1"].
+            createInstance(Ci.nsILoginInfo);
+  login2E = Cc["@mozilla.org/login-manager/loginInfo;1"].
+            createInstance(Ci.nsILoginInfo);
   login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
   login3B = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
   login4  = Cc["@mozilla.org/login-manager/loginInfo;1"].
             createInstance(Ci.nsILoginInfo);
 
   login1.init("http://example.com", null, "http://example.com",
               "", "examplepass", "", "");
   login2A.init("http://example2.com", null, "http://example2.com",
                "user1name", "user1pass", "", "");
   login2B.init("http://example2.com", null, "http://example2.com",
                "user2name", "user2pass", "", "");
+  login2C.init("http://example2.com", null, "http://example2.com",
+               "user3.name@host", "user3pass", "", "");
+  login2D.init("http://example2.com", null, "http://example2.com",
+               "100@beef", "user3pass", "", "");
+  login2E.init("http://example2.com", null, "http://example2.com",
+               "100%beef", "user3pass", "", "");
   login3A.init("http://localhost:8888", null, "mochitest",
                "mochiuser1", "mochipass1", "", "");
   login3B.init("http://localhost:8888", null, "mochitest2",
                "mochiuser2", "mochipass2", "", "");
   login4.init("http://localhost:8888", null, "mochitest3",
                "mochiuser3", "mochipass3-old", "", "");
 
   pwmgr.addLogin(login1);
   pwmgr.addLogin(login2A);
   pwmgr.addLogin(login2B);
+  pwmgr.addLogin(login2C);
+  pwmgr.addLogin(login2D);
+  pwmgr.addLogin(login2E);
   pwmgr.addLogin(login3A);
   pwmgr.addLogin(login3B);
   pwmgr.addLogin(login4);
 }
 
 function finishTest() {
   ok(true, "finishTest removing testing logins...");
   pwmgr.removeLogin(login1);
   pwmgr.removeLogin(login2A);
   pwmgr.removeLogin(login2B);
+  pwmgr.removeLogin(login2C);
+  pwmgr.removeLogin(login2D);
+  pwmgr.removeLogin(login2E);
   pwmgr.removeLogin(login3A);
   pwmgr.removeLogin(login3B);
   pwmgr.removeLogin(login4);
 
   SimpleTest.finish();
 }
 
 /*
@@ -536,16 +554,44 @@ is(pword.value, "user1pass", "Checking r
 // No default password provided, matching login is returned w/o prompting.
 testNum++;
 pword.value = null;
 isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user2name@example2.com",
                                 Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
 ok(isOk, "Checking dialog return value (accept)");
 is(pword.value, "user2pass", "Checking returned password");
 
+// ===== test 17 =====
+// No default password provided, matching login is returned w/o prompting.
+testNum++;
+pword.value = null;
+isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user3%2Ename%40host@example2.com",
+                                Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
+ok(isOk, "Checking dialog return value (accept)");
+is(pword.value, "user3pass", "Checking returned password");
+
+// ===== test 18 =====
+// No default password provided, matching login is returned w/o prompting.
+testNum++;
+pword.value = null;
+isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://100@beef@example2.com",
+                                Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
+ok(isOk, "Checking dialog return value (accept)");
+is(pword.value, "user3pass", "Checking returned password");
+
+// ===== test 19 =====
+// No default password provided, matching login is returned w/o prompting.
+testNum++;
+pword.value = null;
+isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://100%25beef@example2.com",
+                                Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
+ok(isOk, "Checking dialog return value (accept)");
+is(pword.value, "user3pass", "Checking returned password");
+
+
 // XXX test saving a password with  Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY
 
 
 // ===== test 30 =====
 // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt
 testNum = 30;
 pword.value = null;
 startCallbackTimer();