Bug 1428269: Fix profile value truncation for numeric data r=zbraniecki
authorAdam Roach [:abr] <adam@nostrum.com>
Mon, 06 Jul 2020 18:23:24 +0000
changeset 538938 af264b95e019ac61efa1accfdfea5be77f5f339f
parent 538937 aa1e92757043379fc13788ae690522e0b8334f6f
child 538939 4911fdc92832fd17765b31b8a85a96db6a8fe22d
push id37575
push userapavel@mozilla.com
push dateTue, 07 Jul 2020 03:41:19 +0000
treeherdermozilla-central@dd1766e040a2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerszbraniecki
bugs1428269
milestone80.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 1428269: Fix profile value truncation for numeric data r=zbraniecki Differential Revision: https://phabricator.services.mozilla.com/D81630
browser/extensions/formautofill/FormAutofillHandler.jsm
browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -257,23 +257,44 @@ class FormAutofillSection {
       if (!element) {
         continue;
       }
 
       let maxLength = element.maxLength;
       if (
         maxLength === undefined ||
         maxLength < 0 ||
-        profile[key].length <= maxLength
+        profile[key].toString().length <= maxLength
       ) {
         continue;
       }
 
       if (maxLength) {
-        profile[key] = profile[key].substr(0, maxLength);
+        switch (typeof profile[key]) {
+          case "string":
+            profile[key] = profile[key].substr(0, maxLength);
+            break;
+          case "number":
+            // There's no way to truncate a number smaller than a
+            // single digit.
+            if (maxLength < 1) {
+              maxLength = 1;
+            }
+            // The only numbers we store are expiration month/year,
+            // and if they truncate, we want the final digits, not
+            // the initial ones.
+            profile[key] = profile[key] % Math.pow(10, maxLength);
+            break;
+          default:
+            log.warn(
+              "adaptFieldMaxLength: Don't know how to truncate",
+              typeof profile[key],
+              profile[key]
+            );
+        }
       } else {
         delete profile[key];
       }
     }
   }
 
   getAdaptedProfiles(originalProfiles) {
     for (let profile of originalProfiles) {
--- a/browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
+++ b/browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
@@ -1059,16 +1059,90 @@ const TESTCASES = [
   },
   {
     description: "Use placeholder to adjust cc-exp format [mm - - yyyy].",
     document: `<form><input autocomplete="cc-number">
                <input placeholder="mm - - yyyy" autocomplete="cc-exp"></form>`,
     profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
     expectedResult: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
   },
+  {
+    description: "Test maxlength=2 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="2">
+                 <input autocomplete="cc-exp-year" maxlength="2">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [
+      Object.assign({}, DEFAULT_CREDITCARD_RECORD, {
+        "cc-exp-year": 25,
+      }),
+    ],
+  },
+  {
+    description: "Test maxlength=4 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="4">
+                 <input autocomplete="cc-exp-year" maxlength="4">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+  },
+  {
+    description: "Test maxlength=1 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="1">
+                 <input autocomplete="cc-exp-year" maxlength="1">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [
+      Object.assign({}, DEFAULT_CREDITCARD_RECORD, {
+        "cc-exp-year": 5,
+      }),
+    ],
+  },
+  {
+    description: "Test maxlength=0 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="0">
+                 <input autocomplete="cc-exp-year" maxlength="0">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [
+      {
+        guid: DEFAULT_CREDITCARD_RECORD.guid,
+        "cc-exp": DEFAULT_CREDITCARD_RECORD["cc-exp"],
+      },
+    ],
+  },
+  {
+    // It appears that negative values do not get propagated.
+    description: "Test maxlength=-2 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="-2">
+                 <input autocomplete="cc-exp-year" maxlength="-2">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+  },
+  {
+    description: "Test maxlength=10 on numeric fields.",
+    document: `<form>
+                 <input autocomplete="cc-number">
+                 <input autocomplete="cc-exp-month" maxlength="10">
+                 <input autocomplete="cc-exp-year" maxlength="10">
+               </form>`,
+    profileData: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+    expectedResult: [Object.assign({}, DEFAULT_CREDITCARD_RECORD)],
+  },
 ];
 
 for (let testcase of TESTCASES) {
   add_task(async function() {
     info("Starting testcase: " + testcase.description);
 
     let doc = MockDocument.createTestDocument(
       "http://localhost:8080/test/",