Bug 667233 - Backout bug 1147561 to only support formSubmit upgrades so we can use the same logic. r=dolske
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Sun, 29 May 2016 17:15:45 -0700
changeset 338316 ba10f978fe39da744b6fa8ea284b26928713b3da
parent 338315 c57a0e71e7cdf62ba3d443e250e6086368ad0833
child 338317 ae1f10aaf97873ef33f37d35b060bcb5e6889fb9
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs667233, 1147561
milestone49.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 667233 - Backout bug 1147561 to only support formSubmit upgrades so we can use the same logic. r=dolske [mq]: backout_1147561 MozReview-Commit-ID: IKGj6rT1xTX
toolkit/components/passwordmgr/nsLoginInfo.js
toolkit/components/passwordmgr/storage-json.js
toolkit/components/passwordmgr/storage-mozStorage.js
toolkit/components/passwordmgr/test/LoginTestUtils.jsm
toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html
toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
toolkit/components/passwordmgr/test/unit/test_logins_change.js
toolkit/components/passwordmgr/test/unit/test_logins_search.js
--- a/toolkit/components/passwordmgr/nsLoginInfo.js
+++ b/toolkit/components/passwordmgr/nsLoginInfo.js
@@ -1,16 +1,15 @@
 /* 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/. */
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
 
 function nsLoginInfo() {}
 
 nsLoginInfo.prototype = {
 
   classID : Components.ID("{0f2f347c-1e4f-40cc-8efd-792dea70a85e}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsILoginInfo, Ci.nsILoginMetaInfo]),
 
@@ -44,28 +43,18 @@ nsLoginInfo.prototype = {
         this.username      != aLogin.username)
       return false;
 
     if (!ignorePassword && this.password != aLogin.password)
       return false;
 
     // If either formSubmitURL is blank (but not null), then match.
     if (this.formSubmitURL != "" && aLogin.formSubmitURL != "" &&
-        this.formSubmitURL != aLogin.formSubmitURL) {
-      // If we have the same formSubmitURL hostPort we should match (ignore scheme)
-      try {
-        let loginURI = Services.io.newURI(aLogin.formSubmitURL, null, null);
-        let matchURI = Services.io.newURI(this.formSubmitURL, null, null);
-        if (loginURI.hostPort != matchURI.hostPort) {
-          return false;
-        }
-      } catch (e) {
-        return false;
-      }
-    }
+        this.formSubmitURL != aLogin.formSubmitURL)
+      return false;
 
     // The .usernameField and .passwordField values are ignored.
 
     return true;
   },
 
   equals : function (aLogin) {
     if (this.hostname      != aLogin.hostname      ||
--- a/toolkit/components/passwordmgr/storage-json.js
+++ b/toolkit/components/passwordmgr/storage-json.js
@@ -269,50 +269,24 @@ this.LoginManagerStorage_json.prototype 
    * ids in the database.
    */
   _searchLogins(matchData) {
     this._store.ensureDataReady();
 
     let conditions = [];
 
     function match(aLogin) {
-      let returnValue = {
-        match: false,
-        strictMatch: true
-      };
-
       for (let field in matchData) {
         let value = matchData[field];
         switch (field) {
           // Historical compatibility requires this special case
           case "formSubmitURL":
             if (value != null) {
               if (aLogin.formSubmitURL != "" && aLogin.formSubmitURL != value) {
-                // Check for cases that don't have fallback matches.
-                if (value == "" || value == "javascript:" ||
-                    aLogin.formSubmitURL == "javascript:" ||
-                    aLogin.formSubmitURL == null) {
-                  return returnValue;
-                }
-
-                // Check if it matches with a different scheme.
-                let loginURI = Services.io.newURI(aLogin.formSubmitURL, null, null);
-                let matchURI = Services.io.newURI(value, null, null);
-
-                if (loginURI.hostPort != matchURI.hostPort) {
-                  return returnValue; // not a match at all
-                }
-
-                if ((loginURI.scheme != "http" && loginURI.scheme != "https") ||
-                    (matchURI.scheme != "http" && matchURI.scheme != "https")) {
-                  // Not a match at all since we only fallback HTTP <=> HTTPS.
-                  return returnValue;
-                }
-
-                returnValue.strictMatch = false; // not a strict match
+                return false;
               }
               break;
             }
           // Normal cases.
           case "hostname":
           case "httpRealm":
           case "id":
           case "usernameField":
@@ -321,63 +295,51 @@ this.LoginManagerStorage_json.prototype 
           case "encryptedPassword":
           case "guid":
           case "encType":
           case "timeCreated":
           case "timeLastUsed":
           case "timePasswordChanged":
           case "timesUsed":
             if (value == null && aLogin[field]) {
-              return returnValue;
+              return false;
             } else if (aLogin[field] != value) {
-              return returnValue;
+              return false;
             }
             break;
           // Fail if caller requests an unknown property.
           default:
             throw new Error("Unexpected field: " + field);
         }
       }
-      returnValue.match = true;
-      return returnValue;
+      return true;
     }
 
-    let foundLogins = [], foundIds = [], fallbackLogins = [], fallbackIds = [];
+    let foundLogins = [], foundIds = [];
     for (let loginItem of this._store.data.logins) {
-      let result = match(loginItem);
-      if (result.match) {
+      if (match(loginItem)) {
         // Create the new nsLoginInfo object, push to array
         let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
                     createInstance(Ci.nsILoginInfo);
         login.init(loginItem.hostname, loginItem.formSubmitURL,
                    loginItem.httpRealm, loginItem.encryptedUsername,
                    loginItem.encryptedPassword, loginItem.usernameField,
                    loginItem.passwordField);
         // set nsILoginMetaInfo values
         login.QueryInterface(Ci.nsILoginMetaInfo);
         login.guid = loginItem.guid;
         login.timeCreated = loginItem.timeCreated;
         login.timeLastUsed = loginItem.timeLastUsed;
         login.timePasswordChanged = loginItem.timePasswordChanged;
         login.timesUsed = loginItem.timesUsed;
-        // If protocol does not match, use as a fallback login
-        if (result.strictMatch) {
-          foundLogins.push(login);
-          foundIds.push(loginItem.id);
-        } else {
-          fallbackLogins.push(login);
-          fallbackIds.push(loginItem.id);
-        }
+        foundLogins.push(login);
+        foundIds.push(loginItem.id);
       }
     }
 
-    if (!foundLogins.length && fallbackLogins.length) {
-      this.log("_searchLogins: returning", fallbackLogins.length, "fallback logins");
-      return [fallbackLogins, fallbackIds];
-    }
     this.log("_searchLogins: returning", foundLogins.length, "logins");
     return [foundLogins, foundIds];
   },
 
   /**
    * Removes all logins from storage.
    *
    * Disabled hosts are kept, as one presumably doesn't want to erase those.
--- a/toolkit/components/passwordmgr/storage-mozStorage.js
+++ b/toolkit/components/passwordmgr/storage-mozStorage.js
@@ -462,18 +462,18 @@ LoginManagerStorage_mozStorage.prototype
     let conditions = [], params = {};
 
     for (let field in matchData) {
       let value = matchData[field];
       switch (field) {
         // Historical compatibility requires this special case
         case "formSubmitURL":
           if (value != null) {
-              // As we also need to check for different schemes at the URI
-              // this case gets handled by filtering the result of the query.
+              conditions.push("formSubmitURL = :formSubmitURL OR formSubmitURL = ''");
+              params["formSubmitURL"] = value;
               break;
           }
         // Normal cases.
         case "hostname":
         case "httpRealm":
         case "id":
         case "usernameField":
         case "passwordField":
@@ -501,17 +501,17 @@ LoginManagerStorage_mozStorage.prototype
     // Build query
     let query = "SELECT * FROM moz_logins";
     if (conditions.length) {
       conditions = conditions.map(c => "(" + c + ")");
       query += " WHERE " + conditions.join(" AND ");
     }
 
     let stmt;
-    let logins = [], ids = [], fallbackLogins = [], fallbackIds = [];
+    let logins = [], ids = [];
     try {
       stmt = this._dbCreateStatement(query, params);
       // We can't execute as usual here, since we're iterating over rows
       while (stmt.executeStep()) {
         // Create the new nsLoginInfo object, push to array
         let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
                     createInstance(Ci.nsILoginInfo);
         login.init(stmt.row.hostname, stmt.row.formSubmitURL,
@@ -520,47 +520,27 @@ LoginManagerStorage_mozStorage.prototype
                    stmt.row.passwordField);
         // set nsILoginMetaInfo values
         login.QueryInterface(Ci.nsILoginMetaInfo);
         login.guid = stmt.row.guid;
         login.timeCreated = stmt.row.timeCreated;
         login.timeLastUsed = stmt.row.timeLastUsed;
         login.timePasswordChanged = stmt.row.timePasswordChanged;
         login.timesUsed = stmt.row.timesUsed;
-
-        if (login.formSubmitURL == "" || typeof(matchData.formSubmitURL) == "undefined" ||
-            login.formSubmitURL == matchData.formSubmitURL) {
-            logins.push(login);
-            ids.push(stmt.row.id);
-        } else if (login.formSubmitURL != null &&
-                   login.formSubmitURL != "javascript:" &&
-                   matchData.formSubmitURL != "javascript:") {
-          let loginURI = Services.io.newURI(login.formSubmitURL, null, null);
-          let matchURI = Services.io.newURI(matchData.formSubmitURL, null, null);
-
-          if (loginURI.hostPort == matchURI.hostPort &&
-              ((loginURI.scheme == "http" && matchURI.scheme == "https") ||
-              (loginURI.scheme == "https" && matchURI.scheme == "http"))) {
-            fallbackLogins.push(login);
-            fallbackIds.push(stmt.row.id);
-          }
-        }
+        logins.push(login);
+        ids.push(stmt.row.id);
       }
     } catch (e) {
       this.log("_searchLogins failed: " + e.name + " : " + e.message);
     } finally {
       if (stmt) {
         stmt.reset();
       }
     }
 
-    if (!logins.length && fallbackLogins.length) {
-      this.log("_searchLogins: returning " + fallbackLogins.length + " fallback logins");
-      return [fallbackLogins, fallbackIds];
-    }
     this.log("_searchLogins: returning " + logins.length + " logins");
     return [logins, ids];
   },
 
   /* storeDeletedLogin
    *
    * Moves a login to the deleted logins table
    *
@@ -728,30 +708,16 @@ LoginManagerStorage_mozStorage.prototype
         if (stmt) {
           stmt.reset();
         }
       }
       return numLogins;
     };
 
     let resultLogins = _countLoginsHelper(hostname, formSubmitURL, httpRealm);
-    if (resultLogins == 0 && formSubmitURL != null &&
-        formSubmitURL != "" && formSubmitURL != "javascript:") {
-      let formSubmitURI = Services.io.newURI(formSubmitURL, null, null);
-      let newScheme = null;
-      if (formSubmitURI.scheme == "http") {
-        newScheme = "https";
-      } else if (formSubmitURI.scheme == "https") {
-        newScheme = "http";
-      }
-      if (newScheme) {
-        let newFormSubmitURL = newScheme + "://" + formSubmitURI.hostPort;
-        resultLogins = _countLoginsHelper(hostname, newFormSubmitURL, httpRealm);
-      }
-    }
     this.log("_countLogins: counted logins: " + resultLogins);
     return resultLogins;
   },
 
 
   /*
    * uiBusy
    */
--- a/toolkit/components/passwordmgr/test/LoginTestUtils.jsm
+++ b/toolkit/components/passwordmgr/test/LoginTestUtils.jsm
@@ -67,25 +67,16 @@ this.LoginTestUtils = {
    * nsILoginMetaInfo properties in the test.
    */
   assertLoginListsEqual(actual, expected) {
     Assert.equal(expected.length, actual.length);
     Assert.ok(expected.every(e => actual.some(a => a.equals(e))));
   },
 
   /**
-   * Checks that every login in "expected" matches one in "actual".
-   * The comparison uses the "matches" method of nsILoginInfo.
-   */
-  assertLoginListsMatches(actual, expected, ignorePassword) {
-    Assert.equal(expected.length, actual.length);
-    Assert.ok(expected.every(e => actual.some(a => a.matches(e, ignorePassword))));
-  },
-
-  /**
    * Checks that the two provided arrays of strings contain the same values,
    * maybe in a different order, case-sensitively.
    */
   assertDisabledHostsEqual(actual, expected) {
     Assert.deepEqual(actual.sort(), expected.sort());
   },
 
   /**
@@ -170,16 +161,19 @@ this.LoginTestUtils.testData = {
                     "the username", "the password for example.com",
                     "form_field_username", "form_field_password"),
 
       // Forms found on the same host, but with different hostnames in the
       // "action" attribute, are handled independently.
       new LoginInfo("http://www3.example.com", "http://www.example.com", null,
                     "the username", "the password",
                     "form_field_username", "form_field_password"),
+      new LoginInfo("http://www3.example.com", "https://www.example.com", null,
+                    "the username", "the password",
+                    "form_field_username", "form_field_password"),
       new LoginInfo("http://www3.example.com", "http://example.com", null,
                     "the username", "the password",
                     "form_field_username", "form_field_password"),
 
       // It is not possible to store multiple passwords for the same username,
       // however multiple passwords can be stored when the usernames differ.
       // An empty username is a valid case and different from the others.
       new LoginInfo("http://www4.example.com", "http://www4.example.com", null,
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html
@@ -123,22 +123,16 @@ runChecksAfterCommonInit(() => startTest
 <form id='form14' action='formtest.js'> 14
     <!-- variation just to make sure extra text field is still ignored -->
     <input type='text'     name='uname' value=''>
     <input type='password' name='pname' value=''>
     <input type='text'     name='other' value='xxxxxxxx'>
     <button type='submit'>Submit</button>
 </form>
 
-<form id='form15' action='https://mochi.test:8888/tests/formtest.js'> 15
-    <!-- Different scheme for same url, should be filled -->
-    <input type='text'     name='uname' value=''>
-    <input type='password' name='pname' value=''>
-    <button type='submit'>Submit</button>
-</form>
 
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Login Manager: simple form fill **/
 
@@ -160,17 +154,14 @@ function startTest() {
     // 9-14
     checkForm(f++, "testpass", "");
     checkForm(f++, "",         "testuser", "testpass");
     checkForm(f++, "testuser", "testpass", "");
     checkForm(f++, "testpass", "xxxxxxxx");
     checkForm(f++, "xxxxxxxx", "testuser", "testpass");
     checkForm(f++, "testuser", "testpass", "xxxxxxxx");
 
-    //15
-    checkForm(f++, "testuser", "testpass");
-
     SimpleTest.finish();
 }
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
@@ -55,19 +55,16 @@ var setupScript = runInParent(function s
 
   var login8A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAB", "form9pass", "uname", "pword");
   var login8B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAAB", "form9pass", "uname", "pword");
   var login8C = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAABzz", "form9pass", "uname", "pword");
 
-  var login9 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete6", null,
-                               "testuser9", "testpass9", "uname", "pword");
-
   var login10 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete7", null,
                                 "testuser10", "testpass10", "uname", "pword");
 
 
   // try/catch in case someone runs the tests manually, twice.
   try {
     Services.logins.addLogin(login0);
     Services.logins.addLogin(login1);
@@ -76,17 +73,16 @@ var setupScript = runInParent(function s
     Services.logins.addLogin(login4);
     Services.logins.addLogin(login5);
     Services.logins.addLogin(login6A);
     Services.logins.addLogin(login6B);
     Services.logins.addLogin(login7);
     Services.logins.addLogin(login8A);
     Services.logins.addLogin(login8B);
     // login8C is added later
-    Services.logins.addLogin(login9);
     Services.logins.addLogin(login10);
   } catch (e) {
     assert.ok(false, "addLogin threw: " + e);
   }
 
   addMessageListener("addLogin", loginVariableName => {
     let login = eval(loginVariableName);
     assert.ok(!!login, "Login to add is defined: " + loginVariableName);
@@ -159,25 +155,18 @@ var setupScript = runInParent(function s
 
   <!-- test autocomplete dropdown -->
   <form id="form9" action="http://autocomplete5" onsubmit="return false;">
     <input  type="text"       name="uname">
     <input  type="password"   name="pword">
     <button type="submit">Submit</button>
   </form>
 
-  <!-- test for different scheme -->
-  <form id="form10" action="https://autocomplete6" onsubmit="return false;">
-    <input  type="text"       name="uname">
-    <input  type="password"   name="pword">
-    <button type="submit">Submit</button>
-  </form>
-
   <!-- test for onUsernameInput recipe testing -->
-  <form id="form11" action="https://autocomplete7" onsubmit="return false;">
+  <form id="form11" action="http://autocomplete7" onsubmit="return false;">
     <input  type="text"   name="1">
     <input  type="text"   name="2">
     <button type="submit">Submit</button>
   </form>
 
   <!-- tests <form>-less autocomplete -->
   <div id="form12">
      <input  type="text"       name="uname" id="uname">
@@ -747,33 +736,16 @@ add_task(function* test_form9_autocomple
   // check that empty results are cached - bug 496466
   promise0 = notifyMenuChanged(0);
   sendChar("z");
   yield promise0;
   popupState = yield getPopupState();
   is(popupState.open, false, "Check popup stays closed due to cached empty result");
 });
 
-add_task(function* test_form10_formSubmitURLScheme() {
-  // Check that formSubmitURL with different schemes matches
-  uname = $_(10, "uname");
-  pword = $_(10, "pword");
-  restoreForm();
-  let shownPromise = promiseACShown();
-  doKey("down"); // open
-  yield shownPromise;
-
-  // Check first entry
-  doKey("down");
-  checkACForm("", ""); // value shouldn't update
-  doKey("return"); // not "enter"!
-  yield promiseFormsProcessed();
-  checkACForm("testuser9", "testpass9");
-});
-
 add_task(function* test_form11_recipes() {
   yield loadRecipes({
     siteRecipes: [{
       "hosts": ["mochi.test:8888"],
       "usernameSelector": "input[name='1']",
       "passwordSelector": "input[name='2']"
     }],
   });
--- a/toolkit/components/passwordmgr/test/unit/test_logins_change.js
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_change.js
@@ -335,17 +335,17 @@ add_task(function test_deduplicate_login
       results: 17,
     },
     {
       keyset: ["hostname", "username", "password"],
       results: 18,
     },
     {
       keyset: ["hostname", "username", "password", "formSubmitURL"],
-      results: 22,
+      results: 23,
     },
   ];
 
   let logins = TestData.loginList();
 
   for (let testCase of keyCombinations) {
     // Deduplicate the logins using the current testcase keyset.
     let deduped = LoginHelper.dedupeLogins(logins, testCase.keyset);
--- a/toolkit/components/passwordmgr/test/unit/test_logins_search.js
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_search.js
@@ -92,65 +92,16 @@ function checkAllSearches(aQuery, aExpec
   // Test countLogins.
   let count = Services.logins.countLogins(hostname, formSubmitURL, httpRealm)
   do_check_eq(count, expectedLogins.length);
 
   // Test searchLogins.
   checkSearchLogins(aQuery, aExpectedCount);
 }
 
-/**
- * Tests findLogins, searchLogins, and countLogins with a different set of
- * queries for the search and expected resultset.
- *
- * @param {Object} aQuery
- *        The "hostname", "formSubmitURL", and "httpRealm" properties of this
- *        object are passed as parameters to findLogins, countLogins
- *        and searchLogins function.
- * @param {Object} buildQuery
- *        The "hostname", "formSubmitURL", and "httpRealm" properties of the
- *        object used to build the expected logins to have as a result.
- * @param {Number} aExpectedCount
- *        Number of logins from the test data that should be found.  The actual
- *        list of logins is obtained using the buildExpectedLogins helper, and
- *        this value is just used to verify that modifications to the test data
- *        don't make the current test meaningless.
- */
-function checkAllSearchesTwoSets(aQuery, expectedQuery, aExpectedCount)
-{
-  do_print("Testing all search functions for " + JSON.stringify(aQuery) +
-           " and " + JSON.stringify(expectedQuery));
-
-  let expectedLogins = buildExpectedLogins(expectedQuery);
-
-  // 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);
-  do_check_eq(outCount.value, expectedLogins.length);
-  LoginTestUtils.assertLoginListsMatches(logins, expectedLogins, true);
-
-  // Test countLogins.
-  let count = Services.logins.countLogins(hostname, formSubmitURL, httpRealm)
-  do_check_eq(count, expectedLogins.length);
-
-  // Test searchLogins.
-  outCount = {};
-  logins = Services.logins.searchLogins(outCount, newPropertyBag(expectedQuery));
-  do_check_eq(outCount.value, expectedLogins.length);
-  LoginTestUtils.assertLoginListsMatches(logins, expectedLogins, true);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 //// Tests
 
 /**
  * Prepare data for the following tests.
  */
 add_task(function test_initialize()
 {
@@ -160,43 +111,45 @@ add_task(function test_initialize()
 });
 
 /**
  * Tests findLogins, searchLogins, and countLogins with basic queries.
  */
 add_task(function test_search_all_basic()
 {
   // Find all logins, using no filters in the search functions.
-  checkAllSearches({}, 22);
+  checkAllSearches({}, 23);
 
   // Find all form logins, then all authentication logins.
-  checkAllSearches({ httpRealm: null }, 13);
+  checkAllSearches({ httpRealm: null }, 14);
   checkAllSearches({ formSubmitURL: null }, 9);
 
   // Find all form logins on one host, then all authentication logins.
   checkAllSearches({ hostname: "http://www4.example.com",
                      httpRealm: null }, 3);
   checkAllSearches({ hostname: "http://www2.example.org",
                      formSubmitURL: null }, 2);
 
   // Verify that scheme and subdomain are distinct in the hostname.
   checkAllSearches({ hostname: "http://www.example.com" }, 1);
   checkAllSearches({ hostname: "https://www.example.com" }, 1);
   checkAllSearches({ hostname: "https://example.com" }, 1);
-  checkAllSearches({ hostname: "http://www3.example.com" }, 2);
+  checkAllSearches({ hostname: "http://www3.example.com" }, 3);
 
   // Verify that scheme and subdomain are distinct in formSubmitURL.
   checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2);
-  checkAllSearches({ formSubmitURL: "https://www.example.com" }, 1);
+  checkAllSearches({ formSubmitURL: "https://www.example.com" }, 2);
   checkAllSearches({ formSubmitURL: "http://example.com" }, 1);
 
   // Find by formSubmitURL on a single host.
   checkAllSearches({ hostname: "http://www3.example.com",
                      formSubmitURL: "http://www.example.com" }, 1);
   checkAllSearches({ hostname: "http://www3.example.com",
+                     formSubmitURL: "https://www.example.com" }, 1);
+  checkAllSearches({ hostname: "http://www3.example.com",
                      formSubmitURL: "http://example.com" }, 1);
 
   // Find by httpRealm on all hosts.
   checkAllSearches({ httpRealm: "The HTTP Realm" }, 3);
   checkAllSearches({ httpRealm: "ftp://ftp.example.org" }, 1);
   checkAllSearches({ httpRealm: "The HTTP Realm Other" }, 2);
 
   // Find by httpRealm on a single host.
@@ -208,18 +161,18 @@ add_task(function test_search_all_basic(
                      httpRealm: "ftp://example.net" }, 1);
 });
 
 /**
  * Tests searchLogins with advanced queries.
  */
 add_task(function test_searchLogins()
 {
-  checkSearchLogins({ usernameField: "form_field_username" }, 11);
-  checkSearchLogins({ passwordField: "form_field_password" }, 12);
+  checkSearchLogins({ usernameField: "form_field_username" }, 12);
+  checkSearchLogins({ passwordField: "form_field_password" }, 13);
 
   // Find all logins with an empty usernameField, including for authentication.
   checkSearchLogins({ usernameField: "" }, 11);
 
   // Find form logins with an empty usernameField.
   checkSearchLogins({ httpRealm: null,
                       usernameField: "" }, 2);
 
@@ -245,18 +198,19 @@ add_task(function test_searchLogins_inva
 add_task(function test_search_all_full_case_sensitive()
 {
   checkAllSearches({ hostname: "http://www.example.com" }, 1);
   checkAllSearches({ hostname: "http://www.example.com/" }, 0);
   checkAllSearches({ hostname: "http://" }, 0);
   checkAllSearches({ hostname: "example.com" }, 0);
 
   checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2);
+  checkAllSearches({ formSubmitURL: "http://www.example.com/" }, 0);
   checkAllSearches({ formSubmitURL: "http://" }, 0);
-  Assert.throws(() => checkAllSearches({ formSubmitURL: "example.com" }, 0), /NS_ERROR_MALFORMED_URI/);
+  checkAllSearches({ formSubmitURL: "example.com" }, 0);
 
   checkAllSearches({ httpRealm: "The HTTP Realm" }, 3);
   checkAllSearches({ httpRealm: "The http Realm" }, 0);
   checkAllSearches({ httpRealm: "The HTTP" }, 0);
   checkAllSearches({ httpRealm: "Realm" }, 0);
 });
 
 /**
@@ -267,24 +221,8 @@ add_task(function test_search_all_empty(
 {
   checkAllSearches({ hostname: "http://nonexistent.example.com" }, 0);
   checkAllSearches({ formSubmitURL: "http://www.example.com",
                      httpRealm: "The HTTP Realm" }, 0);
 
   checkSearchLogins({ hostname: "" }, 0);
   checkSearchLogins({ id: "1000" }, 0);
 });
-
-
-add_task(function test_search_different_formSubmitURL_scheme()
-{
-  let aQuery = {
-    formSubmitURL: "https://www.example.com",
-    hostname: "http://www.example.com",
-  };
-
-  let buildQuery = {
-    formSubmitURL: "http://www.example.com",
-    hostname: "http://www.example.com",
-  }
-
-  checkAllSearchesTwoSets(aQuery, buildQuery, 1);
-});