Bug 1477798 - Expose whether a fieldName should be automatically persisted on getAutocompleteInfo(). r=baku
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 10 Jan 2019 18:48:39 +0000
changeset 510423 8ba84058447350628db3f23906674e681ff2c927
parent 510422 9c8923903d734aabb5ff566b0da931cb7ee178aa
child 510424 b9002ded5523510c9926c5450bf101d7cbd0be07
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1477798
milestone66.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 1477798 - Expose whether a fieldName should be automatically persisted on getAutocompleteInfo(). r=baku This allows us to centralize the logic about which field names are "sensitive" and shouldn't be saved in things like form history or session history. Differential Revision: https://phabricator.services.mozilla.com/D16128
dom/base/AutocompleteFieldList.h
dom/base/nsContentUtils.cpp
dom/html/test/forms/test_autocompleteinfo.html
dom/webidl/AutocompleteInfo.webidl
--- a/dom/base/AutocompleteFieldList.h
+++ b/dom/base/AutocompleteFieldList.h
@@ -13,16 +13,21 @@
  * The second argument is the string value of the token
  */
 
 #ifndef AUTOCOMPLETE_FIELD_NAME
 #define AUTOCOMPLETE_FIELD_NAME(name_, value_)
 #define DEFINED_AUTOCOMPLETE_FIELD_NAME
 #endif
 
+#ifndef AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+#define AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(name_, value_)
+#define DEFINED_AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+#endif
+
 #ifndef AUTOCOMPLETE_CONTACT_FIELD_NAME
 #define AUTOCOMPLETE_CONTACT_FIELD_NAME(name_, value_)
 #define DEFINED_AUTOCOMPLETE_CONTACT_FIELD_NAME
 #endif
 
 #ifndef AUTOCOMPLETE_FIELD_HINT
 #define AUTOCOMPLETE_FIELD_HINT(name_, value_)
 #define DEFINED_AUTOCOMPLETE_FIELD_HINT
@@ -139,16 +144,26 @@ AUTOCOMPLETE_FIELD_NAME(LANGUAGE, "langu
 AUTOCOMPLETE_FIELD_NAME(BDAY, "bday")
 AUTOCOMPLETE_FIELD_NAME(BDAY_DAY, "bday-day")
 AUTOCOMPLETE_FIELD_NAME(BDAY_MONTH, "bday-month")
 AUTOCOMPLETE_FIELD_NAME(BDAY_YEAR, "bday-year")
 AUTOCOMPLETE_FIELD_NAME(SEX, "sex")
 AUTOCOMPLETE_FIELD_NAME(URL, "url")
 AUTOCOMPLETE_FIELD_NAME(PHOTO, "photo")
 
+// Field for which we don't want to automatically persist the value e.g. in
+// session/form history.
+AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(OFF, "off")
+// passwords:
+AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(CURRENT_PASSWORD, "current-password")
+AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(NEW_PASSWORD, "new-password")
+// credit card numbers
+AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(CC_NUMBER, "cc-number")
+AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(CC_CSC, "cc-csc")
+
 // Contact category types
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL, "tel")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_COUNTRY_CODE, "tel-country-code")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_NATIONAL, "tel-national")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_AREA_CODE, "tel-area-code")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_LOCAL, "tel-local")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_LOCAL_PREFIX, "tel-local-prefix")
 AUTOCOMPLETE_CONTACT_FIELD_NAME(TEL_LOCAL_SUFFIX, "tel-local-suffix")
@@ -179,16 +194,21 @@ AUTOCOMPLETE_CATEGORY(CONTACT, "contact"
 #undef DEFINED_AUTOCOMPLETE_UNSUPPORTED_FIELD_CONTACT_HINT
 #endif
 
 #ifdef DEFINED_AUTOCOMPLETE_FIELD_NAME
 #undef AUTOCOMPLETE_FIELD_NAME
 #undef DEFINED_AUTOCOMPLETE_FIELD_NAME
 #endif
 
+#ifdef DEFINED_AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+#undef AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+#undef DEFINED_AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+#endif
+
 #ifdef DEFINED_AUTOCOMPLETE_CONTACT_FIELD_NAME
 #undef AUTOCOMPLETE_CONTACT_FIELD_NAME
 #undef DEFINED_AUTOCOMPLETE_CONTACT_FIELD_NAME
 #endif
 
 #ifdef DEFINED_AUTOCOMPLETE_FIELD_HINT
 #undef AUTOCOMPLETE_FIELD_HINT
 #undef DEFINED_AUTOCOMPLETE_FIELD_HINT
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -357,16 +357,23 @@ uint32_t nsContentUtils::sInnerOrOuterWi
 // http://www.whatwg.org/specs/web-apps/current-work/#autofill-field-name
 enum AutocompleteUnsupportedFieldName : uint8_t {
 #define AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(name_, value_) \
   eAutocompleteUnsupportedFieldName_##name_,
 #include "AutocompleteFieldList.h"
 #undef AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME
 };
 
+enum AutocompleteNoPersistFieldName : uint8_t {
+#define AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(name_, value_) \
+  eAutocompleteNoPersistFieldName_##name_,
+#include "AutocompleteFieldList.h"
+#undef AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+};
+
 enum AutocompleteUnsupportFieldContactHint : uint8_t {
 #define AUTOCOMPLETE_UNSUPPORTED_FIELD_CONTACT_HINT(name_, value_) \
   eAutocompleteUnsupportedFieldContactHint_##name_,
 #include "AutocompleteFieldList.h"
 #undef AUTOCOMPLETE_UNSUPPORTED_FIELD_CONTACT_HINT
 };
 
 enum AutocompleteFieldName : uint8_t {
@@ -399,16 +406,23 @@ enum AutocompleteCategory {
 
 static const nsAttrValue::EnumTable kAutocompleteUnsupportedFieldNameTable[] = {
 #define AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME(name_, value_) \
   {value_, eAutocompleteUnsupportedFieldName_##name_},
 #include "AutocompleteFieldList.h"
 #undef AUTOCOMPLETE_UNSUPPORTED_FIELD_NAME
     {nullptr, 0}};
 
+static const nsAttrValue::EnumTable kAutocompleteNoPersistFieldNameTable[] = {
+#define AUTOCOMPLETE_NO_PERSIST_FIELD_NAME(name_, value_) \
+  {value_, eAutocompleteNoPersistFieldName_##name_},
+#include "AutocompleteFieldList.h"
+#undef AUTOCOMPLETE_NO_PERSIST_FIELD_NAME
+    {nullptr, 0}};
+
 static const nsAttrValue::EnumTable
     kAutocompleteUnsupportedContactFieldHintTable[] = {
 #define AUTOCOMPLETE_UNSUPPORTED_FIELD_CONTACT_HINT(name_, value_) \
   {value_, eAutocompleteUnsupportedFieldContactHint_##name_},
 #include "AutocompleteFieldList.h"
 #undef AUTOCOMPLETE_UNSUPPORTED_FIELD_CONTACT_HINT
         {nullptr, 0}};
 
@@ -1127,16 +1141,18 @@ nsContentUtils::InternalSerializeAutocom
     if (enumValue.Equals(NS_LITERAL_STRING("off"), eIgnoreCase) ||
         enumValue.Equals(NS_LITERAL_STRING("on"), eIgnoreCase)) {
       if (numTokens > 1) {
         return eAutocompleteAttrState_Invalid;
       }
       enumValue.ToString(str);
       ASCIIToLower(str);
       aInfo.mFieldName.Assign(str);
+      aInfo.mCanAutomaticallyPersist =
+          !enumValue.Equals(NS_LITERAL_STRING("off"), eIgnoreCase);
       return eAutocompleteAttrState_Valid;
     }
 
     // Only allow on/off if form autofill @autocomplete values aren't enabled
     // and it doesn't grant all valid values.
     if (!sIsFormAutofillAutocompleteEnabled && !aGrantAllValidValue) {
       return eAutocompleteAttrState_Invalid;
     }
@@ -1161,16 +1177,19 @@ nsContentUtils::InternalSerializeAutocom
 
     category = eAutocompleteCategory_CONTACT;
   }
 
   enumValue.ToString(str);
   ASCIIToLower(str);
   aInfo.mFieldName.Assign(str);
 
+  aInfo.mCanAutomaticallyPersist = !enumValue.ParseEnumValue(
+      tokenString, kAutocompleteNoPersistFieldNameTable, false);
+
   // We are done if this was the only token.
   if (numTokens == 1) {
     return eAutocompleteAttrState_Valid;
   }
 
   --index;
   tokenString = nsDependentAtomString(aAttrVal->AtomAt(index));
 
--- a/dom/html/test/forms/test_autocompleteinfo.html
+++ b/dom/html/test/forms/test_autocompleteinfo.html
@@ -25,22 +25,25 @@ Test getAutocompleteInfo() on <input> an
 var values = [
   // Missing or empty attribute
   [undefined, {}, ""],
   ["", {}, ""],
 
   // One token
   ["on", {fieldName: "on" }, "on"],
   ["On", {fieldName: "on" }, "on"],
-  ["off", {fieldName: "off" }, "off" ],
+  ["off", {fieldName: "off", canAutomaticallyPersist: false}, "off" ],
   ["name", {fieldName: "name" }, "name"],
   [" name ", {fieldName: "name" }, "name"],
   ["username", {fieldName: "username"}, ""],
   [" username ", {fieldName: "username"}, ""],
-  ["cc-csc", {fieldName: "cc-csc"}, ""],
+  ["current-password", {fieldName: "current-password", canAutomaticallyPersist: false}, ""],
+  ["new-password", {fieldName: "new-password", canAutomaticallyPersist: false}, ""],
+  ["cc-number", {fieldName: "cc-number", canAutomaticallyPersist: false}, "cc-number"],
+  ["cc-csc", {fieldName: "cc-csc", canAutomaticallyPersist: false}, ""],
   ["language", {fieldName: "language"}, ""],
   ["tel-extension", {fieldName: "tel-extension"}, ""],
   ["foobar", {}, ""],
   ["section-blue", {}, ""],
 
   // Two tokens
   ["on off", {}, ""],
   ["off on", {}, ""],
@@ -134,16 +137,18 @@ function testAutocompleteInfoValue(aEnab
       is(info.section, "section" in test[1] ? test[1].section : "",
         "Checking autocompleteInfo.section for " + field + ": " + test[0]);
       is(info.addressType, "addressType" in test[1] ? test[1].addressType : "",
         "Checking autocompleteInfo.addressType for " + field + ": " + test[0]);
       is(info.contactType, "contactType" in test[1] ? test[1].contactType : "",
         "Checking autocompleteInfo.contactType for " + field + ": " + test[0]);
       is(info.fieldName, "fieldName" in test[1] ? test[1].fieldName : "",
         "Checking autocompleteInfo.fieldName for " + field + ": " + test[0]);
+      is(info.canAutomaticallyPersist, "canAutomaticallyPersist" in test[1] ? test[1].canAutomaticallyPersist : true,
+        "Checking autocompleteInfo.canAutomaticallyPersist for " + field + ": " + test[0]);
     }
   }
 }
 
 function testAutocomplete(aField, aType, aEnabled) {
   aField.type = aType;
   if (aEnabled) {
     ok(aField.getAutocompleteInfo() !== null, "getAutocompleteInfo shouldn't return null");
--- a/dom/webidl/AutocompleteInfo.webidl
+++ b/dom/webidl/AutocompleteInfo.webidl
@@ -9,9 +9,10 @@
  * getAutocompleteInfo method.
  */
 
 dictionary AutocompleteInfo {
   DOMString section = "";
   DOMString addressType = "";
   DOMString contactType = "";
   DOMString fieldName = "";
+  boolean canAutomaticallyPersist = true;
 };