Bug 1329248 - Enable 26 more ESLint rules for PSM. r=mgoodwin
authorCykesiopka <cykesiopka.bmo@gmail.com>
Sat, 14 Jan 2017 13:18:03 +0800
changeset 375010 3d9de93bd6ecd8a44eeedda5d8dc18936b3fb675
parent 375009 a5aa102e8f0ff015d21ac4057fa4d47f47192204
child 375011 c4abb503bfcddd2c79f998047bbede6672b6bd0c
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgoodwin
bugs1329248
milestone53.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 1329248 - Enable 26 more ESLint rules for PSM. r=mgoodwin The "no-mixed-spaces-and-tabs" rule is also disabled since there's no point having it enabled when the "no-tabs" rule is also enabled. MozReview-Commit-ID: 49addnnmmvf
security/manager/.eslintrc.js
security/manager/pki/resources/content/device_manager.js
security/manager/pki/resources/content/exceptionDialog.js
security/manager/ssl/X509.jsm
security/manager/ssl/tests/mochitest/browser/head.js
security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html
security/manager/ssl/tests/unit/test_cert_trust.js
security/manager/ssl/tests/unit/test_ocsp_caching.js
security/manager/tools/genHPKPStaticPins.js
security/manager/tools/genRootCAHashes.js
--- a/security/manager/.eslintrc.js
+++ b/security/manager/.eslintrc.js
@@ -1,12 +1,15 @@
 "use strict";
 
 module.exports = { // eslint-disable-line no-undef
   "rules": {
+    // Enforce return statements in callbacks of array methods.
+    "array-callback-return": "error",
+
     // Braces only needed for multi-line arrow function blocks
     "arrow-body-style": ["error", "as-needed"],
 
     // Require spacing around =>
     "arrow-spacing": "error",
 
     // Always require spacing around a single line block
     "block-spacing": "error",
@@ -18,19 +21,28 @@ module.exports = { // eslint-disable-lin
     "comma-style": "error",
 
     // Don't require spaces around computed properties
     "computed-property-spacing": ["error", "never"],
 
     // Functions must always return something or nothing
     "consistent-return": "error",
 
+    // Verify calls of super() in constructors.
+    "constructor-super": "error",
+
     // Require braces around blocks that start a new line
     "curly": ["error", "multi-line"],
 
+    // Require default case in switch statements.
+    "default-case": "error",
+
+    // Require `foo.bar` dot notation instead of `foo["bar"]` notation.
+    "dot-notation": "error",
+
     // Always require a trailing EOL
     "eol-last": "error",
 
     // No spaces between function name and parentheses.
     "func-call-spacing": ["error", "never"],
 
     // Require function* name()
     "generator-star-spacing": ["error", {"before": false, "after": true}],
@@ -51,100 +63,130 @@ module.exports = { // eslint-disable-lin
     "no-alert": "error",
 
     // Use [] instead of Array()
     "no-array-constructor": "error",
 
     // Disallow use of arguments.caller or arguments.callee.
     "no-caller": "error",
 
+    // Disallow likely erroneous `switch` scoped lexical declarations in
+    // case/default clauses.
+    "no-case-declarations": "error",
+
     // Disallow modifying variables of class declarations.
     "no-class-assign": "error",
 
     // Disallow assignment in conditional expressions, except if the assignment
     // is within parentheses.
     "no-cond-assign": ["error", "except-parens"],
 
     // Disallow use of the console API.
     "no-console": "error",
 
     // Disallow modifying variables that are declared using const.
     "no-const-assign": "error",
 
+    // Disallow constant expressions in conditions (except for loops).
+    "no-constant-condition": ["error", { "checkLoops": false }],
+
+    // Disallow control characters in regular expressions.
+    "no-control-regex": "error",
+
     // Disallow use of debugger
     "no-debugger": "error",
 
     // Disallow deletion of variables (deleting properties is fine though).
     "no-delete-var": "error",
 
     // No duplicate arguments in function declarations
     "no-dupe-args": "error",
 
+    // Disallow duplicate class members.
+    "no-dupe-class-members": "error",
+
     // No duplicate keys in object declarations
     "no-dupe-keys": "error",
 
     // No duplicate cases in switch statements
     "no-duplicate-case": "error",
 
     // If an if block ends with a return no need for an else block
     "no-else-return": "error",
 
+    // No empty statements (except for catch blocks).
+    "no-empty": ["error", { "allowEmptyCatch": true }],
+
     // No empty character classes in regex
     "no-empty-character-class": "error",
 
     // Disallow empty destructuring
     "no-empty-pattern": "error",
 
     // Disallow use of eval().
     "no-eval": "error",
 
     // No assigning to exception variable
     "no-ex-assign": "error",
 
+    // Disallow extending of native objects.
+    "no-extend-native": "error",
+
+    // Disallow unnecessary function binding.
+    "no-extra-bind": "error",
+
     // No using !! where casting to boolean is already happening
     "no-extra-boolean-cast": "error",
 
     // No double semicolon
     "no-extra-semi": "error",
 
+    // Disallow case statement fallthrough without explicit `// falls through`
+    // annotation.
+    "no-fallthrough": "error",
+
     // No overwriting defined functions
     "no-func-assign": "error",
 
     // No reassigning native JS objects or read only globals.
     "no-global-assign": "error",
 
+    // Disallow implied eval().
+    "no-implied-eval": "error",
+
     // No invalid regular expressions
     "no-invalid-regexp": "error",
 
     // No odd whitespace characters
     "no-irregular-whitespace": "error",
 
     // No labels.
     "no-labels": "error",
 
     // No single if block inside an else block
     "no-lonely-if": "error",
 
-    // No mixing spaces and tabs in indent
-    "no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
-
     // No unnecessary spacing
     "no-multi-spaces": ["error", { "exceptions": {
       "AssignmentExpression": true,
       "VariableDeclarator": true,
       "ArrayExpression": true,
       "ObjectExpression": true
     }}],
 
     // Nested ternary statements are confusing
     "no-nested-ternary": "error",
 
     // Use {} instead of new Object()
     "no-new-object": "error",
 
+    // Disallow primitive wrapper instances like `new Boolean(false)`, which
+    // seem like they should act like primitives but don't.
+    "no-new-wrappers": "error",
+
     // No Math() or JSON()
     "no-obj-calls": "error",
 
     // No octal literals
     "no-octal": "error",
 
     // No redeclaring variables
     "no-redeclare": "error",
@@ -153,77 +195,122 @@ module.exports = { // eslint-disable-lin
     "no-return-assign": ["error", "always"],
 
     // Disallow self assignment such as |foo = foo|.
     "no-self-assign": "error",
 
     // No unnecessary comparisons
     "no-self-compare": "error",
 
+    // Disallow use of the comma operator.
+    "no-sequences": "error",
+
     // No declaring variables that hide things like arguments
     "no-shadow-restricted-names": "error",
 
     // Disallow sparse arrays, eg. let arr = [,,"error"].
     "no-sparse-arrays": "error",
 
     // Disallow tabs.
     "no-tabs": "error",
 
     // Disallow template literal placeholder syntax in regular strings.
     "no-template-curly-in-string": "error",
 
+    // Disallow use of this/super before calling super() in constructors.
+    "no-this-before-super": "error",
+
     // Disallow throwing literals (eg. |throw "error"| instead of
     // |throw new Error("error")|)
     "no-throw-literal": "error",
 
     // No trailing whitespace
     "no-trailing-spaces": "error",
 
     // No using undeclared variables
     "no-undef": "error",
 
     // Error on newline where a semicolon is needed
     "no-unexpected-multiline": "error",
 
+    // Disallow unmodified loop conditions.
+    "no-unmodified-loop-condition": "error",
+
+    // Disallow ternary operators when simpler alternatives exist.
+    "no-unneeded-ternary": "error",
+
     // No unreachable statements
     "no-unreachable": "error",
 
+    // Disallow unsafe control flow statements in finally blocks.
+    "no-unsafe-finally": "error",
+
     // No expressions where a statement is expected
     "no-unused-expressions": "error",
 
+    // Disallow unnecessary escape usage in strings and regular expressions.
+    "no-useless-escape": "error",
+
+    // Disallow whitespace before properties.
+    "no-whitespace-before-property": "error",
+
     // No using with
     "no-with": "error",
 
+    // Disallow blank line padding within blocks.
+    "padded-blocks": ["error", "never"],
+
     // Require double quote strings to be used, except cases where another quote
     // type is used to avoid escaping.
     "quotes": ["error", "double", { "avoidEscape": true }],
 
     // Always require semicolon at end of statement
     "semi": ["error", "always"],
 
+    // Enforce spacing after semicolons.
+    "semi-spacing": ["error", { "before": false, "after": true }],
+
     // Require space before blocks
     "space-before-blocks": "error",
 
+    // Never use spaces before named function parentheses, but always for async
+    // arrow functions.
+    "space-before-function-paren": ["error", {
+      "anonymous": "ignore",
+      "asyncArrow": "always",
+      "named": "never",
+    }],
+
     // No space padding in parentheses
     "space-in-parens": ["error", "never"],
 
     // Require spaces around operators
     "space-infix-ops": "error",
 
     // ++ and -- should not need spacing
     "space-unary-ops": ["error", { "words": true, "nonwords": false }],
 
     // Require "use strict" to be defined globally in the script.
     "strict": ["error", "global"],
 
     // No comparisons to NaN
     "use-isnan": "error",
 
+    // Enforce valid JSDoc comments.
+    "valid-jsdoc": ["error", {
+      "requireParamDescription": false,
+      "requireReturn": false,
+      "requireReturnDescription": false,
+    }],
+
     // Only check typeof against valid results
-    "valid-typeof": "error"
+    "valid-typeof": "error",
+
+    // Disallow Yoda conditions.
+    "yoda": ["error", "never"],
   },
   "env": {
     "browser": true
   },
   "globals": {
     "Components": false,
     "dump": false
   }
--- a/security/manager/pki/resources/content/device_manager.js
+++ b/security/manager/pki/resources/content/device_manager.js
@@ -272,16 +272,18 @@ function showSlotInfo()
                 bundle.getString("devinfo_stat_loggedin"),
                 "tok_status");
      break;
    case nsIPKCS11Slot.SLOT_READY:
      AddInfoRow(bundle.getString("devinfo_status"),
                 bundle.getString("devinfo_stat_ready"),
                 "tok_status");
      break;
+   default:
+     return;
   }
   AddInfoRow(bundle.getString("devinfo_desc"),
              selected_slot.desc, "slot_desc");
   AddInfoRow(bundle.getString("devinfo_manID"),
              selected_slot.manID, "slot_manID");
   AddInfoRow(bundle.getString("devinfo_hwversion"),
              selected_slot.HWVersion, "slot_hwv");
   AddInfoRow(bundle.getString("devinfo_fwversion"),
--- a/security/manager/pki/resources/content/exceptionDialog.js
+++ b/security/manager/pki/resources/content/exceptionDialog.js
@@ -129,16 +129,20 @@ function checkCert() {
   }
 
   updateCertStatus();
 }
 
 /**
  * Build and return a URI, based on the information supplied in the
  * Certificate Location fields
+ *
+ * @returns {nsIURI}
+ *          URI constructed from the information supplied on success, null
+ *          otherwise.
  */
 function getURI() {
   // Use fixup service instead of just ioservice's newURI since it's quite
   // likely that the host will be supplied without a protocol prefix, resulting
   // in malformed uri exceptions being thrown.
   let fus = Components.classes["@mozilla.org/docshell/urifixup;1"]
                       .getService(Components.interfaces.nsIURIFixup);
   let locationTextBox = document.getElementById("locationTextBox");
@@ -356,13 +360,13 @@ function addException() {
   if (args && args[0]) {
     args[0].exceptionAdded = true;
   }
 
   gDialog.acceptDialog();
 }
 
 /**
- * Returns true if this dialog is in private browsing mode.
+ * @returns {Boolean} Whether this dialog is in private browsing mode.
  */
 function inPrivateBrowsingMode() {
   return PrivateBrowsingUtils.isWindowPrivate(window);
 }
--- a/security/manager/ssl/X509.jsm
+++ b/security/manager/ssl/X509.jsm
@@ -551,17 +551,17 @@ class Time extends DecodedDER {
 
     contents.assertAtEnd();
     this._der.assertAtEnd();
   }
 
   /**
    * Takes a byte that is supposed to be in the ASCII range for "0" to "9".
    * Validates the range and then converts it to the range 0 to 9.
-   * @param {Number} the digit in question (as ASCII in the range ["0", "9"])
+   * @param {Number} d the digit in question (as ASCII in the range ["0", "9"])
    * @return {Number} the numerical value of the digit (in the range [0, 9])
    */
   _validateDigit(d) {
     if (d < "0".charCodeAt(0) || d > "9".charCodeAt(0)) {
       throw new Error(ERROR_TIME_NOT_VALID);
     }
     return d - "0".charCodeAt(0);
   }
--- a/security/manager/ssl/tests/mochitest/browser/head.js
+++ b/security/manager/ssl/tests/mochitest/browser/head.js
@@ -14,19 +14,17 @@ var gCertDB = Cc["@mozilla.org/security/
 var gImportedCerts = [];
 
 registerCleanupFunction(() => {
   for (let cert of gImportedCerts) {
     gCertDB.deleteCertificate(cert);
   }
 });
 
-/**
- * This function serves the same purpose as the one defined in head_psm.js.
- */
+// This function serves the same purpose as the one defined in head_psm.js.
 function pemToBase64(pem) {
   return pem.replace(/-----BEGIN CERTIFICATE-----/, "")
             .replace(/-----END CERTIFICATE-----/, "")
             .replace(/[\r\n]/g, "");
 }
 
 /**
  * Given the filename of a certificate, returns a promise that will resolve with
--- a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html
+++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html
@@ -144,20 +144,25 @@
 
       if (aCallback) {
         aCallback();
       }
     });
   }
 
   /**
-   * Messages received are in this format:
-   *  (BOOTSTRAP|SECURE|INSECURE) testid
-   * For example: "BOOTSTRAP subdom"
-   *          or: "INSECURE otherdom"
+   * @param {DOMWindow} win
+   *        Test window.
+   * @param {Boolean} isPrivate
+   *        Whether the given window is in private browsing mode.
+   * @param {String} data
+   *        A message that is expected to be in this format:
+   *          (BOOTSTRAP|SECURE|INSECURE) testid
+   *        For example: "BOOTSTRAP subdom"
+   *                 or: "INSECURE otherdom"
    */
   function onMessageReceived(win, isPrivate, data) {
     let result = data.split(/\s+/);
     if (result.length != 2) {
       SimpleTest.ok(false, data);
       return;
     }
 
--- a/security/manager/ssl/tests/unit/test_cert_trust.js
+++ b/security/manager/ssl/tests/unit/test_cert_trust.js
@@ -183,18 +183,18 @@ function test_ca_distrust(ee_cert, cert_
 
 function run_test() {
   let certList = [
     "ca",
     "int",
     "ee",
   ];
   let loadedCerts = [];
-  for (let i = 0 ; i < certList.length; i++) {
-    loadedCerts.push(load_cert(certList[i], ",,"));
+  for (let certName of certList) {
+    loadedCerts.push(load_cert(certName, ",,"));
   }
 
   let ca_cert = loadedCerts[0];
   notEqual(ca_cert, null, "CA cert should have successfully loaded");
   let int_cert = loadedCerts[1];
   notEqual(int_cert, null, "Intermediate cert should have successfully loaded");
   let ee_cert = loadedCerts[2];
   notEqual(ee_cert, null, "EE cert should have successfully loaded");
--- a/security/manager/ssl/tests/unit/test_ocsp_caching.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js
@@ -63,17 +63,16 @@ function run_test() {
   do_get_profile();
   Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
   Services.prefs.setIntPref("security.OCSP.enabled", 1);
   Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4);
   add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
 
   let ocspResponder = new HttpServer();
   ocspResponder.registerPrefixHandler("/", function(request, response) {
-
     do_print("gFetchCount: " + gFetchCount);
     let responseFunction = gResponsePattern[gFetchCount];
     Assert.notEqual(undefined, responseFunction);
 
     ++gFetchCount;
     responseFunction(request, response);
   });
   ocspResponder.start(8888);
--- a/security/manager/tools/genHPKPStaticPins.js
+++ b/security/manager/tools/genHPKPStaticPins.js
@@ -435,17 +435,17 @@ function nameToAlias(certName) {
   // remove  non-ascii characters
   certName = certName.replace(/[^[:ascii:]]/g, "_");
   // replace non word characters
   certName = certName.replace(/[^A-Za-z0-9]/g, "_");
 
   return "k" + certName + "Fingerprint";
 }
 
-function compareByName (a, b) {
+function compareByName(a, b) {
   return a.name.localeCompare(b.name);
 }
 
 function genExpirationTime() {
   let now = new Date();
   let nowMillis = now.getTime();
   let expirationMillis = nowMillis + (PINNING_MINIMUM_REQUIRED_MAX_AGE * 1000);
   let expirationMicros = expirationMillis * 1000;
@@ -481,17 +481,17 @@ function writeFingerprints(certNameToSKD
   }
   writeString("};\n");
   writeString("static const StaticFingerprints " + varPrefix + " = {\n  " +
     "sizeof(" + varPrefix + "_Data) / sizeof(const char*),\n  " + varPrefix +
     "_Data\n};\n\n");
 }
 
 function writeEntry(entry) {
-  let printVal = "  { \"" + entry.name + "\",\ ";
+  let printVal = `  { "${entry.name}", `;
   if (entry.include_subdomains) {
     printVal += "true, ";
   } else {
     printVal += "false, ";
   }
   // Default to test mode if not specified.
   let testMode = true;
   if (entry.hasOwnProperty("test_mode")) {
--- a/security/manager/tools/genRootCAHashes.js
+++ b/security/manager/tools/genRootCAHashes.js
@@ -134,19 +134,17 @@ function writeRootHashes(fos) {
       writeString(fos, "      " + hexSlice(fpBytes, 16, 32) + " },\n");
       writeString(fos, "      " + fp.binNumber + " /* Bin Number */\n");
 
       writeString(fos, "  },\n");
     });
     writeString(fos, FP_POSTAMBLE);
 
     writeString(fos, "\n");
-
-  }
-  catch (e) {
+  } catch (e) {
     dump("ERROR: problem writing output: " + e + "\n");
   }
 }
 
 // Scan our list (linearly) for the given fingerprint string
 function findTrustAnchorByFingerprint(sha256Fingerprint) {
   for (let i = 0; i < gTrustAnchors.roots.length; i++) {
     if (sha256Fingerprint == gTrustAnchors.roots[i].sha256Fingerprint) {
@@ -188,17 +186,16 @@ function insertTrustAnchorsFromDatabase(
     // If this is a trusted cert
     if (CertDb.isCertTrusted(cert, CERT_TYPE, TRUST_TYPE)) {
       // Base64 encode the hex string
       let binaryFingerprint = CommonUtils.hexToBytes(stripColons(cert.sha256Fingerprint));
       let encodedFingerprint = btoa(binaryFingerprint);
 
        // Scan to see if this is already in the database.
       if (findTrustAnchorByFingerprint(encodedFingerprint) == ROOT_NOT_ASSIGNED) {
-
         // Let's get a usable name; some old certs do not have CN= filled out
         let label = getLabelForCert(cert);
 
         // Add to list
         gTrustAnchors.maxBin += 1;
         gTrustAnchors.roots.push(
           {
             "label": label,