Bug 1242254 - Enable initial set of eslint rules for PSM. draft
authorCykesiopka <cykesiopka.bmo@gmail.com>
Sun, 24 Jan 2016 02:35:36 -0800
changeset 324863 569088ee5ac11db1ba5b920aaf770e71f273307a
parent 324862 038b2414e772d168451f997954c8a39a7b270789
child 513421 7d27ce02cafb0e6af3c23849aac85ac680ae40af
push id9948
push usercykesiopka.bmo@gmail.com
push dateSun, 24 Jan 2016 10:37:16 +0000
bugs1242254
milestone46.0a1
Bug 1242254 - Enable initial set of eslint rules for PSM. These rules are copied from toolkit/.eslintrc (with non-passing rules excluded and previously commented out and passing rules included).
.eslintignore
security/manager/.eslintrc
security/manager/pki/resources/content/createCertInfo.js
security/manager/pki/resources/content/device_manager.js
security/manager/pki/resources/content/password.js
security/manager/pki/resources/content/pippki.js
security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
security/manager/ssl/tests/unit/test_getchain.js
security/manager/ssl/tests/unit/test_pinning.js
security/manager/ssl/tests/unit/test_signed_dir.js
security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
security/manager/tools/genHPKPStaticPins.js
security/manager/tools/genRootCAHashes.js
security/manager/tools/getHSTSPreloadList.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -34,17 +34,16 @@ modules/**
 mozglue/**
 netwerk/**
 nsprpub/**
 other-licenses/**
 parser/**
 probes/**
 python/**
 rdf/**
-security/**
 services/**
 startupcache/**
 testing/**
 tools/**
 uriloader/**
 view/**
 webapprt/**
 widget/**
new file mode 100644
--- /dev/null
+++ b/security/manager/.eslintrc
@@ -0,0 +1,123 @@
+{
+  "rules": {
+    // Braces only needed for multi-line arrow function blocks
+    "arrow-body-style": [2, "as-needed"],
+
+    // Require spacing around =>
+    "arrow-spacing": 2,
+
+    // Commas at the end of the line not the start
+    "comma-style": 2,
+
+    // Functions must always return something or nothing
+    "consistent-return": 2,
+
+    // Always require a trailing EOL
+    "eol-last": 2,
+
+    // Require function* name()
+    "generator-star-spacing": [2, {"before": false, "after": true}],
+
+    // Space after colon not before in property declarations
+    "key-spacing": [2, { "beforeColon": false, "afterColon": true, "mode": "minimum" }],
+
+    // Unix linebreaks
+    "linebreak-style": [2, "unix"],
+
+    // Always require parenthesis for new calls
+    "new-parens": 2,
+
+    // No duplicate arguments in function declarations
+    "no-dupe-args": 2,
+
+    // No duplicate keys in object declarations
+    "no-dupe-keys": 2,
+
+    // No duplicate cases in switch statements
+    "no-duplicate-case": 2,
+
+    // No labels
+    "no-labels": 2,
+
+    // No empty character classes in regex
+    "no-empty-character-class": 2,
+
+    // Disallow empty destructuring
+    "no-empty-pattern": 2,
+
+    // No assigning to exception variable
+    "no-ex-assign": 2,
+
+    // No using !! where casting to boolean is already happening
+    "no-extra-boolean-cast": 2,
+
+    // No double semicolon
+    "no-extra-semi": 2,
+
+    // No overwriting defined functions
+    "no-func-assign": 2,
+
+    // No invalid regular expressions
+    "no-invalid-regexp": 2,
+
+    // No odd whitespace characters
+    "no-irregular-whitespace": 2,
+
+    // No mixing spaces and tabs in indent
+    "no-mixed-spaces-and-tabs": [2, "smart-tabs"],
+
+    // No reassigning native JS objects
+    "no-native-reassign": 2,
+
+    // No (!foo in bar)
+    "no-negated-in-lhs": 2,
+
+    // Use {} instead of new Object()
+    "no-new-object": 2,
+
+    // No Math() or JSON()
+    "no-obj-calls": 2,
+
+    // No unnecessary comparisons
+    "no-self-compare": 2,
+
+    // No declaring variables that hide things like arguments
+    "no-shadow-restricted-names": 2,
+
+    // No spaces between function name and parentheses
+    "no-spaced-func": 2,
+
+    // Error on newline where a semicolon is needed
+    "no-unexpected-multiline": 2,
+
+    // No unreachable statements
+    "no-unreachable": 2,
+
+    // No expressions where a statement is expected
+    "no-unused-expressions": 2,
+
+    // No using with
+    "no-with": 2,
+
+    // Require space before blocks
+    "space-before-blocks": 2,
+
+    // Require spaces before finally, catch, etc.
+    "space-before-keywords": [2, "always"],
+
+    // No space padding in parentheses
+    "space-in-parens": [2, "never"],
+
+    // Require spaces after return, throw and case
+    "space-return-throw-case": 2,
+
+    // ++ and -- should not need spacing
+    "space-unary-ops": [2, { "words": true, "nonwords": false }],
+
+    // No comparisons to NaN
+    "use-isnan": 2,
+
+    // Only check typeof against valid results
+    "valid-typeof": 2,
+  }
+}
--- a/security/manager/pki/resources/content/createCertInfo.js
+++ b/security/manager/pki/resources/content/createCertInfo.js
@@ -26,11 +26,11 @@ function onLoad()
   
   keygenThread.startKeyGeneration(obs);
 }
 
 function onClose()
 {
   setCursor("default");
 
-  var alreadyClosed = new Object();
+  var alreadyClosed = {};
   keygenThread.userCanceled(alreadyClosed);
 }
--- a/security/manager/pki/resources/content/device_manager.js
+++ b/security/manager/pki/resources/content/device_manager.js
@@ -83,17 +83,17 @@ function RefreshDeviceList()
       var slotnames = [];
       var slots = module.listSlots();
       var slots_done = false;
       try {
         slots.isDone();
       } catch (e) { slots_done = true; }
       while (!slots_done) {
         var slot = null;
- 	try {
+        try {
           slot = slots.currentItem().QueryInterface(nsIPKCS11Slot);
         } catch (e) { slot = null; }
         // in the ongoing discussion of whether slot names or token names
         // are to be shown, I've gone with token names because NSS will
         // prefer lookup by token name.  However, the token may not be
         // present, so maybe slot names should be listed, while token names
         // are "remembered" for lookup?
 	if (slot != null) {
--- a/security/manager/pki/resources/content/password.js
+++ b/security/manager/pki/resources/content/password.js
@@ -41,39 +41,39 @@ function onLoad()
 
   if(tokenName=="") {
      var sectokdb = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
      var tokenList = sectokdb.listTokens();
      var enumElement;
      var i=0;
      var menu = document.getElementById("tokenMenu");
      try {
-        for ( ; !tokenList.isDone(); tokenList.next()) {
+        for (; !tokenList.isDone(); tokenList.next()) {
            enumElement = tokenList.currentItem();
            var token = enumElement.QueryInterface(nsIPK11Token);
            if(token.needsLogin() || !(token.needsUserInit)) {
               var menuItemNode = document.createElement("menuitem");
               menuItemNode.setAttribute("value", token.tokenName);
               menuItemNode.setAttribute("label", token.tokenName);
               menu.firstChild.appendChild(menuItemNode);
               if (i == 0) {
                  menu.selectedItem = menuItemNode;
                  tokenName = token.tokenName;
               }
               i++;
            }
         }
-     }catch(exception){}
+     } catch (exception) {}
   } else {
     var sel = document.getElementById("tokenMenu");
     sel.setAttribute("hidden", "true");
     var tag = document.getElementById("tokenName");
     tag.setAttribute("value",tokenName);
   }
-	 	 
+
   process();
 }
 
 function onMenuChange()
 {
    //get the selected token
    var list = document.getElementById("tokenMenu");
    tokenName = list.value;
@@ -218,63 +218,60 @@ function setP12Password()
   // Return value
   params.SetInt(1, 1);
   // Terminate dialog
   return true;
 }
 
 function setPasswordStrength()
 {
-// Here is how we weigh the quality of the password
-// number of characters
-// numbers
-// non-alpha-numeric chars
-// upper and lower case characters
+  // We weigh the quality of the password by checking the number of:
+  //  - Characters
+  //  - Numbers
+  //  - Non-alphanumeric chars
+  //  - Upper and lower case characters
 
-  var pw=document.getElementById('pw1').value;
-//  doPrompt("password='" + pw +"'");
+  let pw = document.getElementById("pw1").value;
 
-//length of the password
-  var pwlength=(pw.length);
-  if (pwlength>5)
-    pwlength=5;
-
+  let pwlength = pw.length;
+  if (pwlength > 5) {
+    pwlength = 5;
+  }
 
-//use of numbers in the password
-  var numnumeric = pw.replace (/[0-9]/g, "");
-  var numeric=(pw.length - numnumeric.length);
-  if (numeric>3)
-    numeric=3;
+  let numnumeric = pw.replace(/[0-9]/g, "");
+  let numeric= pw.length - numnumeric.length;
+  if (numeric > 3) {
+    numeric = 3;
+  }
 
-//use of symbols in the password
-  var symbols = pw.replace (/\W/g, "");
-  var numsymbols=(pw.length - symbols.length);
-  if (numsymbols>3)
-    numsymbols=3;
+  let symbols = pw.replace(/\W/g, "");
+  let numsymbols = pw.length - symbols.length;
+  if (numsymbols > 3) {
+    numsymbols = 3;
+  }
 
-//use of uppercase in the password
-  var numupper = pw.replace (/[A-Z]/g, "");
-  var upper=(pw.length - numupper.length);
-  if (upper>3)
-    upper=3;
+  let numupper = pw.replace(/[A-Z]/g, "");
+  let upper = pw.length - numupper.length;
+  if (upper > 3) {
+    upper = 3;
+  }
 
-
-  var pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
+  let pwstrength = (pwlength * 10) - 20 + (numeric * 10) + (numsymbols * 15) +
+                   (upper * 10);
 
-  // make sure we're give a value between 0 and 100
-  if ( pwstrength < 0 ) {
+  // Clamp strength to [0, 100].
+  if (pwstrength < 0) {
     pwstrength = 0;
   }
-  
-  if ( pwstrength > 100 ) {
+  if (pwstrength > 100) {
     pwstrength = 100;
   }
 
-  var mymeter=document.getElementById('pwmeter');
-  mymeter.setAttribute("value",pwstrength);
+  let meter = document.getElementById("pwmeter");
+  meter.setAttribute("value", pwstrength);
 
   return;
 }
 
 function checkPasswords()
 {
   var pw1=document.getElementById('pw1').value;
   var pw2=document.getElementById('pw2').value;
--- a/security/manager/pki/resources/content/pippki.js
+++ b/security/manager/pki/resources/content/pippki.js
@@ -59,17 +59,16 @@ function getPEMString(cert)
   var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n");
   return "-----BEGIN CERTIFICATE-----\r\n"
          + wrapped
          + "\r\n-----END CERTIFICATE-----\r\n";
 }
  
 function alertPromptService(title, message)
 {
-  var ps = null;
   var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
            getService(Components.interfaces.nsIPromptService);
   ps.alert(window, title, message);
 }
 
 function exportToFile(parent, cert)
 {
   var bundle = document.getElementById("pippki_bundle");
--- a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
@@ -58,17 +58,17 @@ function test() {
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
       executeSoon(function() { aCallback(aWin); });
     });
-  };
+  }
 
    // this function is called after calling finish() on the test.
   registerCleanupFunction(function() {
     windowsToClose.forEach(function(aWin) {
       aWin.close();
     });
     uri = Services.io.newURI("http://localhost", null, null);
     gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0);
--- a/security/manager/ssl/tests/unit/test_getchain.js
+++ b/security/manager/ssl/tests/unit/test_getchain.js
@@ -39,17 +39,17 @@ function check_matching_issuer_and_getch
         "Expected and actual issuer serial numbers should match");
   let chain = cert.getChain();
   let issuer_via_getchain = chain.queryElementAt(1, nsIX509Cert);
   // The issuer returned by cert.issuer or cert.getchain should be consistent.
   equal(cert.issuer.serialNumber, issuer_via_getchain.serialNumber,
         "Serial numbers via cert.issuer and via getChain() should match");
 }
 
-function check_getchain(ee_cert, ssl_ca, email_ca){
+function check_getchain(ee_cert, ssl_ca, email_ca) {
   // A certificate should first build a chain/issuer to
   // a SSL trust domain, then an EMAIL trust domain and then
   // an object signer trust domain.
 
   const nsIX509Cert = Components.interfaces.nsIX509Cert;
   certdb.setCertTrust(ssl_ca, nsIX509Cert.CA_CERT,
                       Ci.nsIX509CertDB.TRUSTED_SSL);
   certdb.setCertTrust(email_ca, nsIX509Cert.CA_CERT,
--- a/security/manager/ssl/tests/unit/test_pinning.js
+++ b/security/manager/ssl/tests/unit/test_pinning.js
@@ -123,17 +123,17 @@ function test_mitm() {
                       PRErrorCodeSuccess);
   add_connection_test("sub.exclude-subdomains.pinning.example.com",
                       PRErrorCodeSuccess);
   add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess);
   add_cert_override_test("unknownissuer.test-mode.pinning.example.com",
                          Ci.nsICertOverrideService.ERROR_UNTRUSTED,
                          SEC_ERROR_UNKNOWN_ISSUER);
   add_clear_override("unknownissuer.test-mode.pinning.example.com");
-};
+}
 
 function test_disabled() {
   // Disable pinning.
   add_test(function() {
     Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 0);
     run_next_test();
   });
 
--- a/security/manager/ssl/tests/unit/test_signed_dir.js
+++ b/security/manager/ssl/tests/unit/test_signed_dir.js
@@ -72,17 +72,17 @@ function verifyDirAsync(name, expectedRv
 }
 
 
 //
 // the tests
 //
 
 add_test(function() {
-  verifyDirAsync("'valid'", Cr.NS_OK, {} /* no tampering */ );
+  verifyDirAsync("'valid'", Cr.NS_OK, {} /* no tampering */);
 });
 
 add_test(function() {
   verifyDirAsync("'no meta dir'", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED,
                  {delete: ["META-INF"]});
 });
 
 add_test(function() {
@@ -165,9 +165,9 @@ add_test(function() {
 do_register_cleanup(function() {
   if (gTarget.exists()) {
     gTarget.remove(true);
   }
 });
 
 function run_test() {
   run_next_test();
-}
\ No newline at end of file
+}
--- a/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
+++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js
@@ -83,25 +83,25 @@ function test_part1() {
                              "bugzilla.mozilla.org", 0));
   // but this time include subdomains was not set, so test for that
   ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                               "subdomain.bugzilla.mozilla.org", 0));
   gSSService.clearAll();
 
   // check that processing a header with max-age: 0 from a subdomain of a site
   // will not remove that (ancestor) site from the list
-  var uri = Services.io.newURI("http://subdomain.www.torproject.org", null, null);
+  uri = Services.io.newURI("http://subdomain.www.torproject.org", null, null);
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                            "max-age=0", sslStatus, 0);
   ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                              "www.torproject.org", 0));
   ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                               "subdomain.www.torproject.org", 0));
 
-  var uri = Services.io.newURI("http://subdomain.bugzilla.mozilla.org", null, null);
+  uri = Services.io.newURI("http://subdomain.bugzilla.mozilla.org", null, null);
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                            "max-age=0", sslStatus, 0);
   // we received a header with "max-age=0", so we have "no information"
   // regarding the sts state of subdomain.bugzilla.mozilla.org specifically,
   // but it is actually still an STS host, because of the preloaded
   // bugzilla.mozilla.org including subdomains.
   // Here's a drawing:
   // |-- bugzilla.mozilla.org (in preload list, includes subdomains) IS sts host
@@ -134,17 +134,17 @@ function test_part1() {
   // Test that an expired non-private browsing entry results in correctly
   // identifying a host that is on the preload list as no longer sts.
   // (This happens when we're in regular browsing mode, we get a header from
   // a site on the preload list, and that header later expires. We need to
   // then treat that host as no longer an sts host.)
   // (sanity check first - this should be in the preload list)
   ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                              "login.persona.org", 0));
-  var uri = Services.io.newURI("http://login.persona.org", null, null);
+  uri = Services.io.newURI("http://login.persona.org", null, null);
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                            "max-age=1", sslStatus, 0);
   do_timeout(1250, function() {
     ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                                 "login.persona.org", 0));
     run_next_test();
   });
 }
@@ -187,17 +187,17 @@ function test_private_browsing1() {
   // Test that an expired private browsing entry results in correctly
   // identifying a host that is on the preload list as no longer sts.
   // (This happens when we're in private browsing mode, we get a header from
   // a site on the preload list, and that header later expires. We need to
   // then treat that host as no longer an sts host.)
   // (sanity check first - this should be in the preload list)
   ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                              "login.persona.org", IS_PRIVATE));
-  var uri = Services.io.newURI("http://login.persona.org", null, null);
+  uri = Services.io.newURI("http://login.persona.org", null, null);
   gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri,
                            "max-age=1", sslStatus, IS_PRIVATE);
   do_timeout(1250, function() {
     ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS,
                                 "login.persona.org", IS_PRIVATE));
     // Simulate leaving private browsing mode
     Services.obs.notifyObservers(null, "last-pb-context-exited", null);
   });
--- a/security/manager/tools/genHPKPStaticPins.js
+++ b/security/manager/tools/genHPKPStaticPins.js
@@ -121,18 +121,17 @@ function download(filename) {
   try {
     req.send();
   }
   catch (e) {
     throw "ERROR: problem downloading '" + filename + "': " + e;
   }
 
   if (req.status != 200) {
-    throw("ERROR: problem downloading '" + filename + "': status " +
-          req.status);
+    throw `ERROR: problem downloading '${filename}': status ${req.status}`;
   }
 
   let resultDecoded;
   try {
     resultDecoded = atob(req.responseText);
   }
   catch (e) {
     throw "ERROR: could not decode data as base64 from '" + filename + "': " + e;
@@ -331,17 +330,17 @@ function downloadAndParseChromePins(file
     pin.static_spki_hashes.forEach(function(name) {
       if (name in chromeNameToHash) {
         let hash = chromeNameToHash[name];
         pinset.sha256_hashes.push(certSKDToName[hash]);
 
         // We should have already added hashes for all of these when we
         // imported the certificate file.
         if (!certNameToSKD[name]) {
-          throw("No hash for name: " + name);
+          throw "No hash for name: " + name;
         }
       } else if (name in chromeNameToMozName) {
         pinset.sha256_hashes.push(chromeNameToMozName[name]);
       } else {
         dump("Skipping Chrome pinset " + pinset.name + ", couldn't find " +
              "builtin " + name + " from cert file\n");
         valid = false;
       }
@@ -422,17 +421,17 @@ function loadNSSCertinfo(extraCertificat
 function parseJson(filename) {
   let json = stripComments(readFileToString(filename));
   return JSON.parse(json);
 }
 
 function nameToAlias(certName) {
   // change the name to a string valid as a c identifier
   // remove  non-ascii characters
-  certName = certName.replace( /[^[:ascii:]]/g, "_");
+  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) {
   return a.name.localeCompare(b.name);
@@ -499,17 +498,17 @@ function writeEntry(entry) {
   if (entry.is_moz || (entry.pins.indexOf("mozilla") != -1 &&
                        entry.pins != "mozilla_test")) {
     printVal += "true, ";
   } else {
     printVal += "false, ";
   }
   if ("id" in entry) {
     if (entry.id >= 256) {
-      throw("Not enough buckets in histogram");
+      throw "Not enough buckets in histogram";
     }
     if (entry.id >= 0) {
       printVal += entry.id + ", ";
     }
   } else {
     printVal += "-1, ";
   }
   printVal += "&kPinset_" + entry.pins;
--- a/security/manager/tools/genRootCAHashes.js
+++ b/security/manager/tools/genRootCAHashes.js
@@ -161,24 +161,24 @@ function findTrustAnchorByFingerprint(sh
 function getLabelForCert(cert) {
   let label = cert.commonName;
 
   if (label.length < 5) {
     label = cert.subjectName;
   }
 
   // replace non-ascii characters
-  label = label.replace( /[^[:ascii:]]/g, "_");
+  label = label.replace(/[^[:ascii:]]/g, "_");
   // replace non-word characters
-  label = label.replace(/[^A-Za-z0-9]/g ,"_");
+  label = label.replace(/[^A-Za-z0-9]/g, "_");
   return label;
 }
 
 // Fill in the gTrustAnchors list with trust anchors from the database.
-function insertTrustAnchorsFromDatabase(){
+function insertTrustAnchorsFromDatabase() {
   // We only want CA certs for SSL
   const CERT_TYPE = Ci.nsIX509Cert.CA_CERT;
   const TRUST_TYPE = Ci.nsIX509CertDB.TRUSTED_SSL;
 
   // Iterate through the whole Cert DB
   let enumerator = CertDb.getCerts().getEnumerator();
   while (enumerator.hasMoreElements()) {
     let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
--- a/security/manager/tools/getHSTSPreloadList.js
+++ b/security/manager/tools/getHSTSPreloadList.js
@@ -160,17 +160,17 @@ function processStsHeader(host, header, 
            includeSubdomains: includeSubdomains.value,
            error: error,
            retries: host.retries - 1,
            forceInclude: forceInclude,
            originalIncludeSubdomains: host.originalIncludeSubdomains };
 }
 
 // RedirectAndAuthStopper prevents redirects and HTTP authentication
-function RedirectAndAuthStopper() {};
+function RedirectAndAuthStopper() {}
 
 RedirectAndAuthStopper.prototype = {
   // nsIChannelEventSink
   asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) {
     throw Cr.NS_ERROR_ENTITY_CHANGED;
   },
 
   // nsIAuthPrompt2