Bug 1551657 part 3. Stop using [array] in findLogins. r=MattN
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 14 May 2019 19:28:52 +0000
changeset 532760 288bafa86adbbcbdf71e015ac2bc8b15e127f8f8
parent 532759 40d655af6177f18e6e30a4e0933846ca35600661
child 532761 bdbfb93093eeba973bb1e1f3fc2c2697ed4e64c4
push id11272
push userapavel@mozilla.com
push dateThu, 16 May 2019 15:28:22 +0000
treeherdermozilla-beta@2265bfc5920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1551657
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1551657 part 3. Stop using [array] in findLogins. r=MattN I audited the results from https://searchfox.org/mozilla-central/search?q=%5B%5EA-Za-z_%5D%5BFf%5DindLogins%5B%5EA-Za-z_%5D&case=true&regexp=true&path= Differential Revision: https://phabricator.services.mozilla.com/D31119
browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js
browser/components/migration/tests/marionette/test_refresh_firefox.py
mobile/android/chrome/content/PermissionsHelper.js
mobile/android/chrome/content/aboutLogins.js
mobile/android/chrome/content/browser.js
mobile/android/components/PromptService.js
services/fxaccounts/FxAccountsStorage.jsm
services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js
services/sync/modules/browserid_identity.js
services/sync/modules/engines/passwords.js
services/sync/tests/unit/test_password_engine.js
services/sync/tests/unit/test_password_store.js
services/sync/tps/extensions/tps/resource/modules/passwords.jsm
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginManager.jsm
toolkit/components/passwordmgr/LoginManagerPrompter.jsm
toolkit/components/passwordmgr/nsILoginManager.idl
toolkit/components/passwordmgr/nsILoginManagerStorage.idl
toolkit/components/passwordmgr/storage-json.js
toolkit/components/passwordmgr/storage-mozStorage.js
toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js
toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html
toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js
toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js
toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
toolkit/components/passwordmgr/test/unit/test_logins_search.js
toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
--- a/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_browsingData_passwords.js
@@ -10,19 +10,18 @@ const REFERENCE_DATE = Date.now();
 const LOGIN_USERNAME = "username";
 const LOGIN_PASSWORD = "password";
 const LOGIN_USERNAME_FIELD = "username_field";
 const LOGIN_PASSWORD_FIELD = "password_field";
 const OLD_HOST = "http://mozilla.org";
 const NEW_HOST = "http://mozilla.com";
 
 function checkLoginExists(host, shouldExist) {
-  let count = {value: 0};
-  loginManager.findLogins(count, host, "", null);
-  equal(count.value, shouldExist ? 1 : 0, `Login was ${shouldExist ? "" : "not "} found.`);
+  let logins = loginManager.findLogins(host, "", null);
+  equal(logins.length, shouldExist ? 1 : 0, `Login was ${shouldExist ? "" : "not "} found.`);
 }
 
 function addLogin(host, timestamp) {
   checkLoginExists(host, false);
   let login = Cc["@mozilla.org/login-manager/loginInfo;1"]
               .createInstance(Ci.nsILoginInfo);
   login.init(host, "", null, LOGIN_USERNAME, LOGIN_PASSWORD,
              LOGIN_USERNAME_FIELD, LOGIN_PASSWORD_FIELD);
--- a/browser/components/migration/tests/marionette/test_refresh_firefox.py
+++ b/browser/components/migration/tests/marionette/test_refresh_firefox.py
@@ -193,17 +193,17 @@ class TestFirefoxRefresh(MarionetteTestC
           let storage = new FxAccountsStorageManager();
           let data = {email: "test@test.com", uid: "uid", keyFetchToken: "top-secret"};
           storage.initialize(data);
           storage.finalize().then(resolve);
         """)
 
     def checkPassword(self):
         loginInfo = self.marionette.execute_script("""
-          let ary = Services.logins.findLogins({},
+          let ary = Services.logins.findLogins(
             "test.marionette.mozilla.com",
             "http://test.marionette.mozilla.com/some/form/",
             null, {});
           return ary.length ? ary : {username: "null", password: "null"};
         """)
         self.assertEqual(len(loginInfo), 1)
         self.assertEqual(loginInfo[0]['username'], self._username)
         self.assertEqual(loginInfo[0]['password'], self._password)
--- a/mobile/android/chrome/content/PermissionsHelper.js
+++ b/mobile/android/chrome/content/PermissionsHelper.js
@@ -162,17 +162,17 @@ var PermissionsHelper = {
    *        The permission type string stored in permission manager.
    *        e.g. "geolocation", "indexedDB", "popup"
    */
   clearPermission: function clearPermission(aPrincipal, 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.displayPrePath, "", "");
+      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.displayPrePath, true);
     } else {
       Services.perms.removeFromPrincipal(aPrincipal, aType);
       // Clear content prefs set in ContentPermissionPrompt.js
--- a/mobile/android/chrome/content/aboutLogins.js
+++ b/mobile/android/chrome/content/aboutLogins.js
@@ -280,17 +280,17 @@ var Logins = {
 
     try {
       if ((newUsername === origUsername) && (newPassword === origPassword)) {
         Snackbars.show(gStringBundle.GetStringFromName("editLogin.saved1"), Snackbars.LENGTH_LONG);
         this._showList();
         return;
       }
 
-      let logins = Services.logins.findLogins({}, this._selectedLogin.hostname, this._selectedLogin.formSubmitURL, this._selectedLogin.httpRealm);
+      let logins = Services.logins.findLogins(this._selectedLogin.hostname, this._selectedLogin.formSubmitURL, this._selectedLogin.httpRealm);
 
       for (let i = 0; i < logins.length; i++) {
         if (logins[i].username == origUsername) {
           let propBag = Cc["@mozilla.org/hash-property-bag;1"].
             createInstance(Ci.nsIWritablePropertyBag);
           if (newUsername !== origUsername) {
             propBag.setProperty("username", newUsername);
           }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -4216,17 +4216,17 @@ Tab.prototype = {
         }
 
         break;
       }
 
       case "DOMFormHasPassword": {
         // Send logins for this hostname to Java.
         let hostname = aEvent.target.baseURIObject.displayPrePath;
-        let foundLogins = Services.logins.findLogins({}, hostname, "", "");
+        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/mobile/android/components/PromptService.js
+++ b/mobile/android/components/PromptService.js
@@ -362,17 +362,17 @@ InternalPrompt.prototype = {
     let checkMsg = null;
     let check = { value: false };
     let hostname, realm;
     [hostname, realm, aUser] = PromptUtils.getHostnameAndRealm(aPasswordRealm);
 
     let canSave = PromptUtils.canSaveLogin(hostname, aSavePassword);
     if (canSave) {
       // Look for existing logins.
-      let foundLogins = PromptUtils.pwmgr.findLogins({}, hostname, null, realm);
+      let foundLogins = PromptUtils.pwmgr.findLogins(hostname, null, realm);
       [checkMsg, check] = PromptUtils.getUsernameAndPassword(foundLogins, aUser, aPass);
     }
 
     // (eslint-disable: see bug 1177904)
     let ok = false;
     if (aUser)
       ok = this.nsIPrompt_promptUsernameAndPassword(aTitle, aText, aUser, aPass, checkMsg, check); // eslint-disable-line no-undef
     else
@@ -387,17 +387,17 @@ InternalPrompt.prototype = {
   /* ----------  nsIAuthPrompt2  ---------- */
 
   promptAuth: function promptAuth(aChannel, aLevel, aAuthInfo) {
     let checkMsg = null;
     let check = { value: false };
     let message = PromptUtils.makeDialogText(aChannel, aAuthInfo);
     let [username, password] = PromptUtils.getAuthInfo(aAuthInfo);
     let [hostname, httpRealm] = PromptUtils.getAuthTarget(aChannel, aAuthInfo);
-    let foundLogins = PromptUtils.pwmgr.findLogins({}, hostname, null, httpRealm);
+    let foundLogins = PromptUtils.pwmgr.findLogins(hostname, null, httpRealm);
 
     let canSave = PromptUtils.canSaveLogin(hostname, null);
     if (canSave)
       [checkMsg, check] = PromptUtils.getUsernameAndPassword(foundLogins, username, password);
 
     if (username.value && password.value) {
       PromptUtils.setAuthInfo(aAuthInfo, username.value, password.value);
     }
@@ -437,17 +437,17 @@ InternalPrompt.prototype = {
     if (!hashKey)
       return;
 
     // If login manger has logins for this host, defer prompting if we're
     // already waiting on a master password entry.
     let prompt = this._asyncPrompts[hashKey];
     let prompter = prompt.prompter;
     let [hostname, httpRealm] = PromptUtils.getAuthTarget(prompt.channel, prompt.authInfo);
-    let foundLogins = PromptUtils.pwmgr.findLogins({}, hostname, null, httpRealm);
+    let foundLogins = PromptUtils.pwmgr.findLogins(hostname, null, httpRealm);
     if (foundLogins.length > 0 && PromptUtils.pwmgr.uiBusy)
       return;
 
     this._asyncPromptInProgress = true;
     prompt.inProgress = true;
 
     let self = this;
 
--- a/services/fxaccounts/FxAccountsStorage.jsm
+++ b/services/fxaccounts/FxAccountsStorage.jsm
@@ -485,17 +485,17 @@ LoginManagerStorage.prototype = {
   // was unlocked (even if no existing logins existed) or false if it was
   // locked (meaning we don't even know if it existed or not.)
   async _clearLoginMgrData() {
     try { // Services.logins might be third-party and broken...
       await Services.logins.initializationPromise;
       if (!this._isLoggedIn) {
         return false;
       }
-      let logins = Services.logins.findLogins({}, FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
+      let logins = Services.logins.findLogins(FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
       for (let login of logins) {
         Services.logins.removeLogin(login);
       }
       return true;
     } catch (ex) {
       log.error("Failed to clear login data: ${}", ex);
       return false;
     }
@@ -531,17 +531,17 @@ LoginManagerStorage.prototype = {
       let login = new loginInfo(FXA_PWDMGR_HOST,
                                 null, // aFormSubmitURL,
                                 FXA_PWDMGR_REALM, // aHttpRealm,
                                 uid, // aUsername
                                 JSON.stringify(contents), // aPassword
                                 "", // aUsernameField
                                 "");// aPasswordField
 
-      let existingLogins = Services.logins.findLogins({}, FXA_PWDMGR_HOST, null,
+      let existingLogins = Services.logins.findLogins(FXA_PWDMGR_HOST, null,
                                                       FXA_PWDMGR_REALM);
       if (existingLogins.length) {
         Services.logins.modifyLogin(existingLogins[0], login);
       } else {
         Services.logins.addLogin(login);
       }
       log.trace("finished write of user data to the login manager");
     } catch (ex) {
@@ -561,17 +561,17 @@ LoginManagerStorage.prototype = {
       // read the data from the login manager and merge it for return.
       await Services.logins.initializationPromise;
 
       if (!this._isLoggedIn) {
         log.info("returning partial account data as the login manager is locked.");
         throw new this.STORAGE_LOCKED();
       }
 
-      let logins = Services.logins.findLogins({}, FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
+      let logins = Services.logins.findLogins(FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
       if (logins.length == 0) {
         // This could happen if the MP was locked when we wrote the data.
         log.info("Can't find any credentials in the login manager");
         return null;
       }
       let login = logins[0];
       // Support either the uid or the email as the username - as of bug 1183951
       // we store the uid, but we support having either for b/w compat.
--- a/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js
+++ b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js
@@ -21,17 +21,17 @@ LoginManagerStorage.prototype.__defineGe
 function setLoginMgrLoggedInState(loggedIn) {
   isLoggedIn = loggedIn;
 }
 
 
 initTestLogging("Trace");
 
 function getLoginMgrData() {
-  let logins = Services.logins.findLogins({}, FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
+  let logins = Services.logins.findLogins(FXA_PWDMGR_HOST, null, FXA_PWDMGR_REALM);
   if (logins.length == 0) {
     return null;
   }
   Assert.equal(logins.length, 1, "only 1 login available");
   return logins[0];
 }
 
 function createFxAccounts() {
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -343,17 +343,17 @@ this.BrowserIDManager.prototype = {
     // nothing to do here until we decide to migrate away from FxA.
   },
 
   /**
    * Deletes Sync credentials from the password manager.
    */
   deleteSyncCredentials() {
     for (let host of Utils.getSyncCredentialsHosts()) {
-      let logins = Services.logins.findLogins({}, host, "", "");
+      let logins = Services.logins.findLogins(host, "", "");
       for (let login of logins) {
         Services.logins.removeLogin(login);
       }
     }
   },
 
   /**
    * Verify the current auth state, unlocking the master-password if necessary.
--- a/services/sync/modules/engines/passwords.js
+++ b/services/sync/modules/engines/passwords.js
@@ -80,17 +80,17 @@ PasswordEngine.prototype = {
   async _syncFinish() {
     await SyncEngine.prototype._syncFinish.call(this);
 
     // Delete the Weave credentials from the server once.
     if (!Svc.Prefs.get("deletePwdFxA", false)) {
       try {
         let ids = [];
         for (let host of Utils.getSyncCredentialsHosts()) {
-          for (let info of Services.logins.findLogins({}, host, "", "")) {
+          for (let info of Services.logins.findLogins(host, "", "")) {
             ids.push(info.QueryInterface(Ci.nsILoginMetaInfo).guid);
           }
         }
         if (ids.length) {
           let coll = new Collection(this.engineURL, null, this.service);
           coll.ids = ids;
           let ret = await coll.delete();
           this._log.debug("Delete result: " + ret);
@@ -115,17 +115,17 @@ PasswordEngine.prototype = {
   },
 
   async _findDupe(item) {
     let login = this._store._nsLoginInfoFromRecord(item);
     if (!login) {
       return null;
     }
 
-    let logins = Services.logins.findLogins({}, login.hostname, login.formSubmitURL, login.httpRealm);
+    let logins = Services.logins.findLogins(login.hostname, login.formSubmitURL, login.httpRealm);
 
     await Async.promiseYield(); // Yield back to main thread after synchronous operation.
 
     // Look for existing logins that match the hostname, but ignore the password.
     for (let local of logins) {
       if (login.matches(local, true) && local instanceof Ci.nsILoginMetaInfo) {
         return local.guid;
       }
--- a/services/sync/tests/unit/test_password_engine.js
+++ b/services/sync/tests/unit/test_password_engine.js
@@ -100,17 +100,17 @@ add_task(async function test_password_en
 
   _("Add new login to upload during first sync");
   let newLogin;
   {
     let login = new LoginInfo("https://example.com", "", null, "username",
       "password", "", "");
     Services.logins.addLogin(login);
 
-    let logins = Services.logins.findLogins({}, "https://example.com", "", "");
+    let logins = Services.logins.findLogins("https://example.com", "", "");
     equal(logins.length, 1, "Should find new login in login manager");
     newLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
 
     // Insert a server record that's older, so that we prefer the local one.
     let rec = new LoginRec("passwords", newLogin.guid);
     rec.formSubmitURL = newLogin.formSubmitURL;
     rec.httpRealm = newLogin.httpRealm;
     rec.hostname = newLogin.hostname;
@@ -130,17 +130,17 @@ add_task(async function test_password_en
       "0ldpa55", "", "");
     Services.logins.addLogin(login);
 
     let props = new PropertyBag();
     let localPasswordChangeTime = Date.now() - 1 * 60 * 60 * 24 * 1000;
     props.setProperty("timePasswordChanged", localPasswordChangeTime);
     Services.logins.modifyLogin(login, props);
 
-    let logins = Services.logins.findLogins({}, "https://mozilla.com", "", "");
+    let logins = Services.logins.findLogins("https://mozilla.com", "", "");
     equal(logins.length, 1, "Should find old login in login manager");
     oldLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
     equal(oldLogin.timePasswordChanged, localPasswordChangeTime);
 
     let rec = new LoginRec("passwords", oldLogin.guid);
     rec.hostname = oldLogin.hostname;
     rec.formSubmitURL = oldLogin.formSubmitURL;
     rec.httpRealm = oldLogin.httpRealm;
@@ -159,17 +159,17 @@ add_task(async function test_password_en
 
   try {
     await sync_engine_and_validate_telem(engine, false);
 
     let newRec = collection.cleartext(newLogin.guid);
     equal(newRec.password, "password",
       "Should update remote password for newer login");
 
-    let logins = Services.logins.findLogins({}, "https://mozilla.com", "", "");
+    let logins = Services.logins.findLogins("https://mozilla.com", "", "");
     equal(logins[0].password, "n3wpa55",
       "Should update local password for older login");
   } finally {
     await cleanup(engine, server);
   }
 });
 
 add_task(async function test_password_dupe() {
@@ -202,17 +202,17 @@ add_task(async function test_password_du
 
   _("Create local record with same details and guid1");
   await engine._store.create(Object.assign({}, details, { id: guid1 }));
 
   try {
     _("Perform sync");
     await sync_engine_and_validate_telem(engine, false);
 
-    let logins = Services.logins.findLogins({}, "https://www.example.com", "", "");
+    let logins = Services.logins.findLogins("https://www.example.com", "", "");
 
     equal(logins.length, 1);
     equal(logins[0].QueryInterface(Ci.nsILoginMetaInfo).guid, guid2);
     equal(null, collection.payload(guid1));
   } finally {
     await cleanup(engine, server);
   }
 });
--- a/services/sync/tests/unit/test_password_store.js
+++ b/services/sync/tests/unit/test_password_store.js
@@ -6,24 +6,23 @@ const {Service} = ChromeUtils.import("re
 
 
 async function checkRecord(name, record, expectedCount, timeCreated,
                      expectedTimeCreated, timePasswordChanged,
                      expectedTimePasswordChanged, recordIsUpdated) {
   let engine = Service.engineManager.get("passwords");
   let store = engine._store;
 
-  let count = {};
-  let logins = Services.logins.findLogins(count, record.hostname,
+  let logins = Services.logins.findLogins(record.hostname,
                                           record.formSubmitURL, null);
 
   _("Record" + name + ":" + JSON.stringify(logins));
-  _("Count" + name + ":" + count.value);
+  _("Count" + name + ":" + logins.length);
 
-  Assert.equal(count.value, expectedCount);
+  Assert.equal(logins.length, expectedCount);
 
   if (expectedCount > 0) {
     Assert.ok(!!(await store.getAllIDs())[record.id]);
     let stored_record = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
 
     if (timeCreated !== undefined) {
       Assert.equal(stored_record.timeCreated, expectedTimeCreated);
     }
@@ -165,30 +164,28 @@ add_task(async function run_test() {
 
   let engine = Service.engineManager.get("passwords");
   let store = engine._store;
 
   try {
     Assert.equal((await store.applyIncomingBatch([recordA, recordB])).length, 0);
 
     // Only the good record makes it to Services.logins.
-    let badCount = {};
-    let goodCount = {};
-    let badLogins = Services.logins.findLogins(badCount, recordA.hostname,
+    let badLogins = Services.logins.findLogins(recordA.hostname,
                                                recordA.formSubmitURL,
                                                recordA.httpRealm);
-    let goodLogins = Services.logins.findLogins(goodCount, recordB.hostname,
+    let goodLogins = Services.logins.findLogins(recordB.hostname,
                                                 recordB.formSubmitURL, null);
 
     _("Bad: " + JSON.stringify(badLogins));
     _("Good: " + JSON.stringify(goodLogins));
-    _("Count: " + badCount.value + ", " + goodCount.value);
+    _("Count: " + badLogins.length + ", " + goodLogins.length);
 
-    Assert.equal(goodCount.value, 1);
-    Assert.equal(badCount.value, 0);
+    Assert.equal(goodLogins.length, 1);
+    Assert.equal(badLogins.length, 0);
 
     Assert.ok(!!(await store.getAllIDs())[BOGUS_GUID_B]);
     Assert.ok(!(await store.getAllIDs())[BOGUS_GUID_A]);
 
     await test_LoginRec_toString(store, recordB);
 
     await test_apply_records_with_times("http://afoo.baz.com", undefined, undefined);
     await test_apply_records_with_times("http://bfoo.baz.com", 1000, undefined);
--- a/services/sync/tps/extensions/tps/resource/modules/passwords.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/passwords.jsm
@@ -93,18 +93,17 @@ Password.prototype = {
    * Find
    *
    * Finds a password entry in the login manager, for the password
    * represented by this object's properties.
    *
    * @return the guid of the password if found, otherwise -1
    */
   Find() {
-    let logins = Services.logins.findLogins({},
-                                            this.props.hostname,
+    let logins = Services.logins.findLogins(this.props.hostname,
                                             this.props.submitURL,
                                             this.props.realm);
     for (var i = 0; i < logins.length; i++) {
       if (logins[i].username == this.props.username &&
           logins[i].password == this.props.password &&
           logins[i].usernameField == this.props.usernameField &&
           logins[i].passwordField == this.props.passwordField) {
         logins[i].QueryInterface(Ci.nsILoginMetaInfo);
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -722,17 +722,17 @@ var LoginHelper = {
 
         if (foundMatchingNewLogin) {
           continue;
         }
       }
 
       // While here we're passing formSubmitURL and httpRealm, they could be empty/null and get
       // ignored in that case, leading to multiple logins for the same username.
-      let existingLogins = Services.logins.findLogins({}, login.hostname,
+      let existingLogins = Services.logins.findLogins(login.hostname,
                                                       login.formSubmitURL,
                                                       login.httpRealm);
       // Check for an existing login that matches *including* the password.
       // If such a login exists, we do not need to add a new login.
       if (existingLogins.some(l => login.matches(l, false /* ignorePassword */))) {
         continue;
       }
       // Now check for a login with the same username, where it may be that we have an
--- a/toolkit/components/passwordmgr/LoginManager.jsm
+++ b/toolkit/components/passwordmgr/LoginManager.jsm
@@ -253,17 +253,17 @@ LoginManager.prototype = {
 
   /**
    * Add a new login to login storage.
    */
   addLogin(login) {
     this._checkLogin(login);
 
     // Look for an existing entry.
-    var logins = this.findLogins({}, login.hostname, login.formSubmitURL,
+    var logins = this.findLogins(login.hostname, login.formSubmitURL,
                                  login.httpRealm);
 
     if (logins.some(l => login.matches(l, true))) {
       throw new Error("This login already exists.");
     }
 
     log.debug("Adding login");
     return this._storage.addLogin(login);
@@ -360,22 +360,21 @@ LoginManager.prototype = {
     log.debug("getAllDisabledHosts: returning", disabledHosts.length, "disabled hosts.");
     return disabledHosts;
   },
 
 
   /**
    * Search for the known logins for entries matching the specified criteria.
    */
-  findLogins(count, origin, formActionOrigin, httpRealm) {
+  findLogins(origin, formActionOrigin, httpRealm) {
     log.debug("Searching for logins matching origin:", origin,
               "formActionOrigin:", formActionOrigin, "httpRealm:", httpRealm);
 
-    return this._storage.findLogins(count, origin, formActionOrigin,
-                                    httpRealm);
+    return this._storage.findLogins(origin, formActionOrigin, httpRealm);
   },
 
 
   /**
    * Public wrapper around _searchLogins to convert the nsIPropertyBag to a
    * JavaScript object and decrypt the results.
    *
    * @return {nsILoginInfo[]} which are decrypted.
--- a/toolkit/components/passwordmgr/LoginManagerPrompter.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerPrompter.jsm
@@ -374,18 +374,17 @@ LoginManagerPrompter.prototype = {
       }
 
       // if checkBoxLabel is null, the checkbox won't be shown at all.
       if (canRememberLogin) {
         checkBoxLabel = this._getLocalizedString("rememberPassword");
       }
 
       // Look for existing logins.
-      var foundLogins = Services.logins.findLogins({}, hostname, null,
-                                                   realm);
+      var foundLogins = Services.logins.findLogins(hostname, null, realm);
 
       // XXX Like the original code, we can't deal with multiple
       // account selection. (bug 227632)
       if (foundLogins.length > 0) {
         selectedLogin = foundLogins[0];
 
         // If the caller provided a username, try to use it. If they
         // provided only a password, this will try to find a password-only
@@ -478,18 +477,17 @@ LoginManagerPrompter.prototype = {
 
       // if checkBoxLabel is null, the checkbox won't be shown at all.
       if (canRememberLogin) {
         checkBoxLabel = this._getLocalizedString("rememberPassword");
       }
 
       if (!aPassword.value) {
         // Look for existing logins.
-        var foundLogins = Services.logins.findLogins({}, hostname, null,
-                                                     realm);
+        var foundLogins = Services.logins.findLogins(hostname, null, realm);
 
         // XXX Like the original code, we can't deal with multiple
         // account selection (bug 227632). We can deal with finding the
         // account based on the supplied username - but in this case we'll
         // just return the first match.
         for (var i = 0; i < foundLogins.length; ++i) {
           if (foundLogins[i].username == username) {
             aPassword.value = foundLogins[i].password;
--- a/toolkit/components/passwordmgr/nsILoginManager.idl
+++ b/toolkit/components/passwordmgr/nsILoginManager.idl
@@ -142,45 +142,39 @@ interface nsILoginManager : nsISupports 
    */
   void setLoginSavingEnabled(in AString aHost, in boolean isEnabled);
 
 
   /**
    * Search for logins matching the specified criteria. Called when looking
    * for logins that might be applicable to a form or authentication request.
    *
-   * @param count
-   *        The number of elements in the array. JS callers can simply use
-   *        the array's .length property, and supply an dummy object for
-   *        this out param. For example: |findLogins({}, hostname, ...)|
    * @param aHostname
    *        The hostname to restrict searches to, in URL format. For
    *        example: "http://www.site.com".
    *        To find logins for a given nsIURI, you would typically pass in
    *        its prePath.
    * @param aActionURL
    *        For form logins, this argument should be the URL to which the
    *        form will be submitted. For protocol logins, specify null.
    *        An empty string ("") will match any value (except null).
    * @param aHttpRealm
    *        For protocol logins, this argument should be the HTTP Realm
    *        for which the login applies. This is obtained from the
    *        WWW-Authenticate header. See RFC2617. For form logins,
    *        specify null.
    *        An empty string ("") will match any value (except null).
-   * @param logins
-   *        An array of nsILoginInfo objects.
+   * @return An array of nsILoginInfo objects.
    *
    * NOTE: This can be called from JS as:
-   *       var logins = pwmgr.findLogins({}, hostname, ...);
+   *       var logins = pwmgr.findLogins(hostname, ...);
    *
    */
-  void findLogins(out unsigned long count, in AString aHostname,
-                  in AString aActionURL,   in AString aHttpRealm,
-                  [retval, array, size_is(count)] out nsILoginInfo logins);
+  Array<nsILoginInfo> findLogins(in AString aHostname, in AString aActionURL,
+				 in AString aHttpRealm);
 
 
   /**
    * Search for logins matching the specified criteria, as with
    * findLogins(). This interface only returns the number of matching
    * logins (and not the logins themselves), which allows a caller to
    * check for logins without causing the user to be prompted for a master
    * password to decrypt the logins.
--- a/toolkit/components/passwordmgr/nsILoginManagerStorage.idl
+++ b/toolkit/components/passwordmgr/nsILoginManagerStorage.idl
@@ -140,41 +140,35 @@ interface nsILoginManagerStorage : nsISu
   void searchLogins(out unsigned long count, in nsIPropertyBag matchData,
                     [retval, array, size_is(count)] out nsILoginInfo logins);
 
 
   /**
    * Search for logins matching the specified criteria. Called when looking
    * for logins that might be applicable to a form or authentication request.
    *
-   * @param count
-   *        The number of elements in the array. JS callers can simply use
-   *        the array's .length property, and supply an dummy object for
-   *        this out param. For example: |findLogins({}, hostname, ...)|
    * @param aHostname
    *        The hostname to restrict searches to, in URL format. For
    *        example: "http://www.site.com".
    * @param aActionURL
    *        For form logins, this argument should be the URL to which the
    *        form will be submitted. For protocol logins, specify null.
    * @param aHttpRealm
    *        For protocol logins, this argument should be the HTTP Realm
    *        for which the login applies. This is obtained from the
    *        WWW-Authenticate header. See RFC2617. For form logins,
    *        specify null.
-   * @param logins
-   *        An array of nsILoginInfo objects.
+   * @return An array of nsILoginInfo objects.
    *
    * NOTE: This can be called from JS as:
-   *       var logins = pwmgr.findLogins({}, hostname, ...);
+   *       var logins = pwmgr.findLogins(hostname, ...);
    *
    */
-  void findLogins(out unsigned long count, in AString aHostname,
-                  in AString aActionURL,   in AString aHttpRealm,
-                  [retval, array, size_is(count)] out nsILoginInfo logins);
+  Array<nsILoginInfo> findLogins(in AString aHostname, in AString aActionURL,
+				 in AString aHttpRealm);
 
 
   /**
    * Search for logins matching the specified criteria, as with
    * findLogins(). This interface only returns the number of matching
    * logins (and not the logins themselves), which allows a caller to
    * check for logins without causing the user to be prompted for a master
    * password to decrypt the logins.
--- a/toolkit/components/passwordmgr/storage-json.js
+++ b/toolkit/components/passwordmgr/storage-json.js
@@ -205,17 +205,17 @@ this.LoginManagerStorage_json.prototype 
     // Check if the new GUID is duplicate.
     if (newLogin.guid != oldStoredLogin.guid &&
         !this._isGuidUnique(newLogin.guid)) {
       throw new Error("specified GUID already exists");
     }
 
     // Look for an existing entry in case key properties changed.
     if (!newLogin.matches(oldLogin, true)) {
-      let logins = this.findLogins({}, newLogin.hostname,
+      let logins = this.findLogins(newLogin.hostname,
                                    newLogin.formSubmitURL,
                                    newLogin.httpRealm);
 
       if (logins.some(login => newLogin.matches(login, true))) {
         throw new Error("This login already exists.");
       }
     }
 
@@ -390,17 +390,17 @@ this.LoginManagerStorage_json.prototype 
 
     this.log("Removing all logins");
     this._store.data.logins = [];
     this._store.saveSoon();
 
     LoginHelper.notifyStorageChanged("removeAllLogins", null);
   },
 
-  findLogins(count, hostname, formSubmitURL, httpRealm) {
+  findLogins(hostname, formSubmitURL, httpRealm) {
     let loginData = {
       hostname,
       formSubmitURL,
       httpRealm,
     };
     let matchData = { };
     for (let field of ["hostname", "formSubmitURL", "httpRealm"]) {
       if (loginData[field] != "") {
@@ -408,17 +408,16 @@ this.LoginManagerStorage_json.prototype 
       }
     }
     let [logins, ids] = this._searchLogins(matchData);
 
     // Decrypt entries found for the caller.
     logins = this._decryptLogins(logins);
 
     this.log("_findLogins: returning", logins.length, "logins");
-    count.value = logins.length; // needed for XPCOM
     return logins;
   },
 
   countLogins(hostname, formSubmitURL, httpRealm) {
     let loginData = {
       hostname,
       formSubmitURL,
       httpRealm,
--- a/toolkit/components/passwordmgr/storage-mozStorage.js
+++ b/toolkit/components/passwordmgr/storage-mozStorage.js
@@ -325,17 +325,17 @@ LoginManagerStorage_mozStorage.prototype
     // Check if the new GUID is duplicate.
     if (newLogin.guid != oldStoredLogin.guid &&
         !this._isGuidUnique(newLogin.guid)) {
       throw new Error("specified GUID already exists");
     }
 
     // Look for an existing entry in case key properties changed.
     if (!newLogin.matches(oldLogin, true)) {
-      let logins = this.findLogins({}, newLogin.hostname,
+      let logins = this.findLogins(newLogin.hostname,
                                    newLogin.formSubmitURL,
                                    newLogin.httpRealm);
 
       if (logins.some(login => newLogin.matches(login, true))) {
         throw new Error("This login already exists.");
       }
     }
 
@@ -601,17 +601,17 @@ LoginManagerStorage_mozStorage.prototype
         stmt.reset();
       }
     }
 
     LoginHelper.notifyStorageChanged("removeAllLogins", null);
   },
 
 
-  findLogins(count, hostname, formSubmitURL, httpRealm) {
+  findLogins(hostname, formSubmitURL, httpRealm) {
     let loginData = {
       hostname,
       formSubmitURL,
       httpRealm,
     };
     let matchData = { };
     for (let field of ["hostname", "formSubmitURL", "httpRealm"]) {
       if (loginData[field] != "") {
@@ -619,17 +619,16 @@ LoginManagerStorage_mozStorage.prototype
       }
     }
     let [logins, ids] = this._searchLogins(matchData);
 
     // Decrypt entries found for the caller.
     logins = this._decryptLogins(logins);
 
     this.log("_findLogins: returning " + logins.length + " logins");
-    count.value = logins.length; // needed for XPCOM
     return logins;
   },
 
 
   countLogins(hostname, formSubmitURL, httpRealm) {
     let _countLoginsHelper = (hostname, formSubmitURL, httpRealm) => {
       // Do checks for null and empty strings, adjust conditions and params
       let [conditions, params] =
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js
@@ -34,54 +34,54 @@ async function togglePasswords() {
   pwmgrdlg.document.querySelector("#togglePasswords").doCommand();
   await ContentTaskUtils.waitForCondition(() => !signonsTree.columns.getNamedColumn("passwordCol").hidden,
                                           "Waiting for Passwords Column to Show/Hide");
   await new Promise(resolve => waitForFocus(resolve, pwmgrdlg));
   pwmgrdlg.document.documentElement.clientWidth; // flush to ensure UI up-to-date
 }
 
 async function editUsernamePromises(site, oldUsername, newUsername) {
-  is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found");
-  let login = Services.logins.findLogins({}, site, "", "")[0];
+  is(Services.logins.findLogins(site, "", "").length, 1, "Correct login found");
+  let login = Services.logins.findLogins(site, "", "")[0];
   is(login.username, oldUsername, "Correct username saved");
   is(getUsername(0), oldUsername, "Correct username shown");
   let focusPromise = BrowserTestUtils.waitForEvent(signonsTree.inputField, "focus", true);
   synthesizeDblClickOnCell(signonsTree, 1, 0);
   await focusPromise;
 
   EventUtils.sendString(newUsername, pwmgrdlg);
   let signonsIntro = doc.querySelector("#signonsIntro");
   EventUtils.sendMouseEvent({type: "click"}, signonsIntro, pwmgrdlg);
   await ContentTaskUtils.waitForCondition(() => !signonsTree.getAttribute("editing"),
                                           "Waiting for editing to stop");
 
-  is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login replaced");
-  login = Services.logins.findLogins({}, site, "", "")[0];
+  is(Services.logins.findLogins(site, "", "").length, 1, "Correct login replaced");
+  login = Services.logins.findLogins(site, "", "")[0];
   is(login.username, newUsername, "Correct username updated");
   is(getUsername(0), newUsername, "Correct username shown after the update");
 }
 
 async function editPasswordPromises(site, oldPassword, newPassword) {
-  is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found");
-  let login = Services.logins.findLogins({}, site, "", "")[0];
+  is(Services.logins.findLogins(site, "", "").length, 1, "Correct login found");
+  let login = Services.logins.findLogins(site, "", "")[0];
   is(login.password, oldPassword, "Correct password saved");
   is(getPassword(0), oldPassword, "Correct password shown");
 
   let focusPromise = BrowserTestUtils.waitForEvent(signonsTree.inputField, "focus", true);
   synthesizeDblClickOnCell(signonsTree, 2, 0);
   await focusPromise;
 
   EventUtils.sendString(newPassword, pwmgrdlg);
   let signonsIntro = doc.querySelector("#signonsIntro");
   EventUtils.sendMouseEvent({type: "click"}, signonsIntro, pwmgrdlg);
   await ContentTaskUtils.waitForCondition(() => !signonsTree.getAttribute("editing"),
                                           "Waiting for editing to stop");
 
-  is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login replaced");
-  login = Services.logins.findLogins({}, site, "", "")[0];
+  is(Services.logins.findLogins(site, "", "").length, 1, "Correct login replaced");
+  login = Services.logins.findLogins(site, "", "")[0];
   is(login.password, newPassword, "Correct password updated");
   is(getPassword(0), newPassword, "Correct password shown after the update");
 }
 
 add_task(async function test_setup() {
   registerCleanupFunction(function() {
     Services.logins.removeAllLogins();
   });
--- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html
@@ -156,21 +156,21 @@ add_task(async function test_noAutologin
   action = {
     buttonClick: "ok",
   };
   proxyAuthinfo.username = "";
   proxyAuthinfo.password = "";
   proxyAuthinfo.realm    = "Proxy Realm";
   proxyAuthinfo.flags    = Ci.nsIAuthInformation.AUTH_PROXY;
 
-  var time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  var time1 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
   promptDone = handlePrompt(state, action);
   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
   await promptDone;
-  var time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  var time2 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
 
   ok(isOk, "Checking dialog return value (accept)");
   isnot(time1, time2, "Checking that timeLastUsed was updated");
   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
 });
 
 add_task(async function test_autologin() {
@@ -179,19 +179,19 @@ add_task(async function test_autologin()
   // Enable the autologin pref.
   SpecialPowers.Services.prefs.setBoolPref("signon.autologin.proxy", true);
 
   proxyAuthinfo.username = "";
   proxyAuthinfo.password = "";
   proxyAuthinfo.realm    = "Proxy Realm";
   proxyAuthinfo.flags    = Ci.nsIAuthInformation.AUTH_PROXY;
 
-  let time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  let time1 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
-  let time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  let time2 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
 
   ok(isOk, "Checking dialog return value (accept)");
   isnot(time1, time2, "Checking that timeLastUsed was updated");
   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
 });
 
 add_task(async function test_autologin_incorrect() {
@@ -215,21 +215,21 @@ add_task(async function test_autologin_i
     buttonClick: "ok",
   };
 
   proxyAuthinfo.username = "";
   proxyAuthinfo.password = "";
   proxyAuthinfo.realm    = "Proxy Realm";
   proxyAuthinfo.flags    = (Ci.nsIAuthInformation.AUTH_PROXY | Ci.nsIAuthInformation.PREVIOUS_FAILED);
 
-  let time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  let time1 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
   promptDone = handlePrompt(state, action);
   isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
   await promptDone;
-  let time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
+  let time2 = pwmgr.findLogins(mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
 
   ok(isOk, "Checking dialog return value (accept)");
   isnot(time1, time2, "Checking that timeLastUsed was updated");
   is(proxyAuthinfo.username, "proxuser", "Checking returned username");
   is(proxyAuthinfo.password, "proxpass", "Checking returned password");
 });
 
 add_task(async function test_autologin_private() {
--- a/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js
+++ b/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js
@@ -66,27 +66,27 @@ add_task(function test_addLogin_wildcard
  * that have an empty formSubmitURL in the store, even when a formSubmitURL is
  * specified.
  */
 add_task(function test_search_all_wildcard() {
   // Search a given formSubmitURL on any host.
   let matchData = newPropertyBag({ formSubmitURL: "http://www.example.com" });
   Assert.equal(Services.logins.searchLogins({}, matchData).length, 2);
 
-  Assert.equal(Services.logins.findLogins({}, "", "http://www.example.com",
+  Assert.equal(Services.logins.findLogins("", "http://www.example.com",
                                           null).length, 2);
 
   Assert.equal(Services.logins.countLogins("", "http://www.example.com",
                                            null), 2);
 
   // Restrict the search to one host.
   matchData.setProperty("hostname", "http://any.example.com");
   Assert.equal(Services.logins.searchLogins({}, matchData).length, 1);
 
-  Assert.equal(Services.logins.findLogins({}, "http://any.example.com",
+  Assert.equal(Services.logins.findLogins("http://any.example.com",
                                           "http://www.example.com",
                                           null).length, 1);
 
   Assert.equal(Services.logins.countLogins("http://any.example.com",
                                            "http://www.example.com",
                                            null), 1);
 });
 
--- a/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js
@@ -33,17 +33,17 @@ add_task(function test_logins_decrypt_fa
     Services.logins.addLogin(loginInfo);
   }
 
   // This makes the existing logins non-decryptable.
   resetMasterPassword();
 
   // These functions don't see the non-decryptable entries anymore.
   Assert.equal(Services.logins.getAllLogins().length, 0);
-  Assert.equal(Services.logins.findLogins({}, "", "", "").length, 0);
+  Assert.equal(Services.logins.findLogins("", "", "").length, 0);
   Assert.equal(Services.logins.searchLogins({}, newPropertyBag()).length, 0);
   Assert.throws(() => Services.logins.modifyLogin(logins[0], newPropertyBag()),
                 /No matching logins/);
   Assert.throws(() => Services.logins.removeLogin(logins[0]),
                 /No matching logins/);
 
   // The function that counts logins sees the non-decryptable entries also.
   Assert.equal(Services.logins.countLogins("", "", ""), logins.length);
@@ -51,17 +51,17 @@ add_task(function test_logins_decrypt_fa
   // Equivalent logins can be added.
   for (let loginInfo of logins) {
     Services.logins.addLogin(loginInfo);
   }
   LoginTestUtils.checkLogins(logins);
   Assert.equal(Services.logins.countLogins("", "", ""), logins.length * 2);
 
   // Finding logins doesn't return the non-decryptable duplicates.
-  Assert.equal(Services.logins.findLogins({}, "http://www.example.com",
+  Assert.equal(Services.logins.findLogins("http://www.example.com",
                                           "", "").length, 1);
   let matchData = newPropertyBag({ hostname: "http://www.example.com" });
   Assert.equal(Services.logins.searchLogins({}, matchData).length, 1);
 
   // Removing single logins does not remove non-decryptable logins.
   for (let loginInfo of TestData.loginList()) {
     Services.logins.removeLogin(loginInfo);
   }
--- a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
@@ -19,17 +19,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
 var gLooksLikeUUIDRegex = /^\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}$/;
 
 /**
  * Retrieves the only login among the current data that matches the hostname of
  * the given nsILoginInfo.  In case there is more than one login for the
  * hostname, the test fails.
  */
 function retrieveLoginMatching(aLoginInfo) {
-  let logins = Services.logins.findLogins({}, aLoginInfo.hostname, "", "");
+  let logins = Services.logins.findLogins(aLoginInfo.hostname, "", "");
   Assert.equal(logins.length, 1);
   return logins[0].QueryInterface(Ci.nsILoginMetaInfo);
 }
 
 /**
  * Checks that the nsILoginInfo and nsILoginMetaInfo properties of two different
  * login instances are equal.
  */
--- a/toolkit/components/passwordmgr/test/unit/test_logins_search.js
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_search.js
@@ -69,20 +69,17 @@ function checkAllSearches(aQuery, aExpec
   // The findLogins and countLogins functions support wildcard matches by
   // specifying empty strings as parameters, while searchLogins requires
   // omitting the property entirely.
   let hostname = ("hostname" in aQuery) ? aQuery.hostname : "";
   let formSubmitURL = ("formSubmitURL" in aQuery) ? aQuery.formSubmitURL : "";
   let httpRealm = ("httpRealm" in aQuery) ? aQuery.httpRealm : "";
 
   // Test findLogins.
-  let outCount = {};
-  let logins = Services.logins.findLogins(outCount, hostname, formSubmitURL,
-                                          httpRealm);
-  Assert.equal(outCount.value, expectedLogins.length);
+  let logins = Services.logins.findLogins(hostname, formSubmitURL, httpRealm);
   LoginTestUtils.assertLoginListsEqual(logins, expectedLogins);
 
   // Test countLogins.
   let count = Services.logins.countLogins(hostname, formSubmitURL, httpRealm);
   Assert.equal(count, expectedLogins.length);
 
   // Test searchLogins.
   checkSearchLogins(aQuery, aExpectedCount);
--- a/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
+++ b/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
@@ -100,19 +100,18 @@ function add_login(aHost) {
  * Checks to see if a login exists for a host.
  *
  * @param aHost
  *        The host to check for the test login.
  * @param aExists
  *        True if the login should exist, false otherwise.
  */
 function check_login_exists(aHost, aExists) {
-  let count = { value: 0 };
-  Services.logins.findLogins(count, aHost, "", null);
-  Assert.equal(count.value, aExists ? 1 : 0);
+  let logins = Services.logins.findLogins(aHost, "", null);
+  Assert.equal(logins.length, aExists ? 1 : 0);
 }
 
 /**
  * Adds a permission for the specified URI to the permission manager.
  *
  * @param aURI
  *        The URI to add the test permission for.
  */