Bug 886764 - [Contacts API] we can have empty strings in the "telMatch" index resulting in matching these contacts for invalid phone numbers in findByIndex. r=gwagner, a=leo+
authorReuben Morais <reuben.morais@gmail.com>
Sun, 28 Jul 2013 20:34:18 -0700
changeset 119819 658f625177cae97ae7d3e2cab8f0ea3ffcd8f797
parent 119818 44de5fb4e8d0b73c1167945b139fc108fd15cf21
child 119820 b32a6a58c97da091655f4f7e20d2aedf3d177c3d
push id1011
push userryanvm@gmail.com
push dateMon, 29 Jul 2013 22:55:57 +0000
reviewersgwagner, leo
bugs886764
milestone18.1
Bug 886764 - [Contacts API] we can have empty strings in the "telMatch" index resulting in matching these contacts for invalid phone numbers in findByIndex. r=gwagner, a=leo+
dom/contacts/fallback/ContactDB.jsm
--- a/dom/contacts/fallback/ContactDB.jsm
+++ b/dom/contacts/fallback/ContactDB.jsm
@@ -13,17 +13,17 @@ const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
 Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
 
 const DB_NAME = "contacts";
-const DB_VERSION = 13;
+const DB_VERSION = 14;
 const STORE_NAME = "contacts";
 const SAVED_GETALL_STORE_NAME = "getallcache";
 const CHUNK_SIZE = 20;
 const CHUNK_INTERVAL = 500;
 const REVISION_STORE = "revision";
 const REVISION_KEY = "revision";
 
 function ContactDispatcher(aContacts, aFullContacts, aCallback, aNewTxn, aClearDispatcher) {
@@ -474,17 +474,47 @@ ContactDB.prototype = {
               cursor.continue();
             } else {
               next();
             }
           }.bind(this);
         } else {
           next();
         }
-      }
+      },
+      function upgrade13to14() {
+        if (DEBUG) debug("Cleaning up empty substring entries in telMatch index");
+        if (!objectStore) {
+          objectStore = aTransaction.objectStore(STORE_NAME);
+        }
+        objectStore.openCursor().onsuccess = function(event) {
+          function removeEmptyStrings(value) {
+            if (value) {
+              const oldLength = value.length;
+              for (let i = 0; i < value.length; ++i) {
+                if (!value[i] || value[i] == "null") {
+                  value.splice(i, 1);
+                }
+              }
+              return oldLength !== value.length;
+            }
+          }
+
+          let cursor = event.target.result;
+          if (cursor) {
+            let modified = removeEmptyStrings(cursor.value.search.parsedTel);
+            let modified2 = removeEmptyStrings(cursor.value.search.tel);
+            if (modified || modified2) {
+              cursor.update(cursor.value);
+            }
+          } else {
+            next();
+          }
+        };
+      },
     ];
 
     let index = aOldVersion;
     let outer = this;
     function next() {
       if (index == aNewVersion) {
         if (aOldVersion === 0) {
           loadInitialContacts();
@@ -591,20 +621,24 @@ ContactDB.prototype = {
                 if (parsedNumber && parsedNumber.nationalFormat) {
                   let number = PhoneNumberUtils.normalize(parsedNumber.nationalFormat);
                   for (let i = 0; i < number.length; i++) {
                     containsSearch[number.substring(i, number.length)] = 1;
                   }
                 }
               }
               for (let num in containsSearch) {
-                contact.search.tel.push(num);
+                if (num != "null") {
+                  contact.search.tel.push(num);
+                }
               }
               for (let num in matchSearch) {
-                contact.search.parsedTel.push(num);
+                if (num != "null") {
+                  contact.search.parsedTel.push(num);
+                }
               }
             } else if ((field == "impp" || field == "email") && aContact.properties[field][i].value) {
               let value = aContact.properties[field][i].value;
               if (value && typeof value == "string") {
                 contact.search[field].push(value.toLowerCase());
               }
             } else {
               let val = aContact.properties[field][i];
@@ -950,16 +984,22 @@ ContactDB.prototype = {
         let index = store.index("telMatch");
         let normalized = PhoneNumberUtils.normalize(options.filterValue,
                                                     /*numbersOnly*/ true);
 
         // Some countries need special handling for number matching. Bug 877302
         if (this.substringMatching && normalized.length > this.substringMatching) {
           normalized = normalized.slice(-this.substringMatching);
         }
+
+        if (!normalized.length) {
+          dump("ContactDB: normalized filterValue is empty, can't perform match search.\n");
+          return txn.abort();
+        }
+
         request = index.mozGetAll(normalized, limit);
       } else {
         // not case sensitive
         let lowerCase = options.filterValue.toString().toLowerCase();
         if (key === "tel") {
           let origLength = lowerCase.length;
           let tmp = PhoneNumberUtils.normalize(lowerCase, /*numbersOnly*/ true);
           if (tmp.length != origLength) {