Repository: zmap/zlint
Pull request #300 (2019-08-01 17:44:37)

lints: consistently name lints by lint status result.
Prior to recently I had been contributing lints without matching the project convention of naming the lint with a prefix based on its potential lint status result (e.g. `e_` for `lints.Error`, `w_` for `lints.Warn`, etc). :sweat: 

This branch fixes the `Name` of all of the lints that didn't match the convention and adds a new test in `zlint_test.go` that will enforce that all new lints meet the convention moving forward.

cpu: @zakird Hold on merging this one for a second. I found a few more and added a test.
cpu: @zakird Ok, should be ready to review now. Sorry about that. I really wanted to add a test so that I wouldn't have to remember to catch this on my future PRs :laughing: 

Patch:
diff --git a/lints/lint_ct_sct_policy_count_unsatisfied.go b/lints/lint_ct_sct_policy_count_unsatisfied.go
index b9edc426..0cc6c87b 100644
--- a/lints/lint_ct_sct_policy_count_unsatisfied.go
+++ b/lints/lint_ct_sct_policy_count_unsatisfied.go
@@ -146,7 +146,7 @@ func appleCTPolicyExpectedSCTs(cert *x509.Certificate) int {
 
 func init() {
 	RegisterLint(&Lint{
-		Name:          "ct_sct_policy_count_unsatisfied",
+		Name:          "w_ct_sct_policy_count_unsatisfied",
 		Description:   "Check if certificate has enough embedded SCTs to meet Apple CT Policy",
 		Citation:      "https://support.apple.com/en-us/HT205280",
 		Source:        AppleCTPolicy,
diff --git a/lints/lint_ext_tor_service_descriptor_hash_invalid.go b/lints/lint_ext_tor_service_descriptor_hash_invalid.go
index 984c98a8..dbb6807d 100644
--- a/lints/lint_ext_tor_service_descriptor_hash_invalid.go
+++ b/lints/lint_ext_tor_service_descriptor_hash_invalid.go
@@ -200,7 +200,7 @@ func (l *torServiceDescHashInvalid) Execute(c *x509.Certificate) *LintResult {
 
 func init() {
 	RegisterLint(&Lint{
-		Name:          "ext_tor_service_descriptor_hash_invalid",
+		Name:          "e_ext_tor_service_descriptor_hash_invalid",
 		Description:   "certificates with .onion names need valid TorServiceDescriptors in extension",
 		Citation:      "BRS: Ballot 201",
 		Source:        CABFBaselineRequirements,
diff --git a/lints/lint_onion_subject_validity_time_too_large.go b/lints/lint_onion_subject_validity_time_too_large.go
index 23b2529f..ef52e8ef 100644
--- a/lints/lint_onion_subject_validity_time_too_large.go
+++ b/lints/lint_onion_subject_validity_time_too_large.go
@@ -56,7 +56,7 @@ func (l *torValidityTooLarge) Execute(c *x509.Certificate) *LintResult {
 
 func init() {
 	RegisterLint(&Lint{
-		Name: "onion_subject_validity_time_too_large",
+		Name: "e_onion_subject_validity_time_too_large",
 		Description: fmt.Sprintf(
 			"certificates with .onion names can not be valid for more than %d months",
 			maxOnionValidityMonths),
diff --git a/lints/lint_san_dns_name_onion_not_ev_cert.go b/lints/lint_san_dns_name_onion_not_ev_cert.go
index 287b7317..01f41452 100644
--- a/lints/lint_san_dns_name_onion_not_ev_cert.go
+++ b/lints/lint_san_dns_name_onion_not_ev_cert.go
@@ -62,7 +62,7 @@ func (l *onionNotEV) Execute(c *x509.Certificate) *LintResult {
 
 func init() {
 	RegisterLint(&Lint{
-		Name:          "san_dns_name_onion_not_ev_cert",
+		Name:          "e_san_dns_name_onion_not_ev_cert",
 		Description:   "certificates with a .onion subject name must be issued in accordance with EV Guidelines",
 		Citation:      "CABF Ballot 144",
 		Source:        CABFBaselineRequirements,
diff --git a/lints/lint_subject_contains_malformed_arpa_ip.go b/lints/lint_subject_contains_malformed_arpa_ip.go
index 69ca0348..50100c1f 100644
--- a/lints/lint_subject_contains_malformed_arpa_ip.go
+++ b/lints/lint_subject_contains_malformed_arpa_ip.go
@@ -129,7 +129,7 @@ func lintReversedIPAddressLabels(name string, ipv6 bool) error {
 
 func init() {
 	RegisterLint(&Lint{
-		Name:          "subject_contains_malformed_arpa_ip",
+		Name:          "w_subject_contains_malformed_arpa_ip",
 		Description:   "Checks no subject domain name contains a rDNS entry in an .arpa zone with the wrong number of labels",
 		Citation:      "BRs: 7.1.4.2.1",
 		Source:        CABFBaselineRequirements,
diff --git a/lints/lint_subject_contains_reserved_arpa_ip.go b/lints/lint_subject_contains_reserved_arpa_ip.go
index b3b6ad95..fd224711 100644
--- a/lints/lint_subject_contains_reserved_arpa_ip.go
+++ b/lints/lint_subject_contains_reserved_arpa_ip.go
@@ -222,7 +222,7 @@ func lintReversedIPAddress(name string, ipv6 bool) error {
 
 func init() {
 	RegisterLint(&Lint{
-		Name:          "subject_contains_reserved_arpa_ip",
+		Name:          "e_subject_contains_reserved_arpa_ip",
 		Description:   "Checks no subject domain name contains a rDNS entry in an .arpa zone specifying a reserved IP address",
 		Citation:      "BRs: 7.1.4.2.1",
 		Source:        CABFBaselineRequirements,


Test patch:
diff --git a/lints/lint_ct_sct_policy_count_unsatisfied_test.go b/lints/lint_ct_sct_policy_count_unsatisfied_test.go
index 8b7c29fe..b3a2132c 100644
--- a/lints/lint_ct_sct_policy_count_unsatisfied_test.go
+++ b/lints/lint_ct_sct_policy_count_unsatisfied_test.go
@@ -102,7 +102,7 @@ func TestSCTCountPolicyUnsatisified(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.Filename)
-			result := Lints["ct_sct_policy_count_unsatisfied"].Execute(ReadCertificate(inputPath))
+			result := Lints["w_ct_sct_policy_count_unsatisfied"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/lints/lint_ext_tor_service_descriptor_hash_invalid_test.go b/lints/lint_ext_tor_service_descriptor_hash_invalid_test.go
index db3935fc..cc7ea1df 100644
--- a/lints/lint_ext_tor_service_descriptor_hash_invalid_test.go
+++ b/lints/lint_ext_tor_service_descriptor_hash_invalid_test.go
@@ -63,7 +63,7 @@ func TestTorDescHashInvalid(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.InputFilename)
-			result := Lints["ext_tor_service_descriptor_hash_invalid"].Execute(ReadCertificate(inputPath))
+			result := Lints["e_ext_tor_service_descriptor_hash_invalid"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/lints/lint_onion_subject_validity_time_too_large_test.go b/lints/lint_onion_subject_validity_time_too_large_test.go
index 200f6f72..e0be93b1 100644
--- a/lints/lint_onion_subject_validity_time_too_large_test.go
+++ b/lints/lint_onion_subject_validity_time_too_large_test.go
@@ -31,7 +31,7 @@ func TestTorValidityTooLarge(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.InputFilename)
-			result := Lints["onion_subject_validity_time_too_large"].Execute(ReadCertificate(inputPath))
+			result := Lints["e_onion_subject_validity_time_too_large"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/lints/lint_san_dns_name_onion_not_ev_cert_test.go b/lints/lint_san_dns_name_onion_not_ev_cert_test.go
index 3f924031..526f2b7f 100644
--- a/lints/lint_san_dns_name_onion_not_ev_cert_test.go
+++ b/lints/lint_san_dns_name_onion_not_ev_cert_test.go
@@ -33,7 +33,7 @@ func TestOnionNotEV(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.InputFilename)
-			result := Lints["san_dns_name_onion_not_ev_cert"].Execute(ReadCertificate(inputPath))
+			result := Lints["e_san_dns_name_onion_not_ev_cert"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/lints/lint_subject_contains_malformed_arpa_ip_test.go b/lints/lint_subject_contains_malformed_arpa_ip_test.go
index 9949214a..f1603b34 100644
--- a/lints/lint_subject_contains_malformed_arpa_ip_test.go
+++ b/lints/lint_subject_contains_malformed_arpa_ip_test.go
@@ -61,7 +61,7 @@ func TestSubjectMalformedDNSARPA(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.InputFilename)
-			result := Lints["subject_contains_malformed_arpa_ip"].Execute(ReadCertificate(inputPath))
+			result := Lints["w_subject_contains_malformed_arpa_ip"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/lints/lint_subject_contains_reserved_arpa_ip_test.go b/lints/lint_subject_contains_reserved_arpa_ip_test.go
index 7acf8097..f6339e62 100644
--- a/lints/lint_subject_contains_reserved_arpa_ip_test.go
+++ b/lints/lint_subject_contains_reserved_arpa_ip_test.go
@@ -63,7 +63,7 @@ func TestSubjectReverseDNSARPA(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.Name, func(t *testing.T) {
 			inputPath := fmt.Sprintf("%s%s", testCaseDir, tc.InputFilename)
-			result := Lints["subject_contains_reserved_arpa_ip"].Execute(ReadCertificate(inputPath))
+			result := Lints["e_subject_contains_reserved_arpa_ip"].Execute(ReadCertificate(inputPath))
 			if result.Status != tc.ExpectedResult {
 				t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
 			}
diff --git a/zlint_test.go b/zlint_test.go
new file mode 100644
index 00000000..05e9fad7
--- /dev/null
+++ b/zlint_test.go
@@ -0,0 +1,30 @@
+package zlint
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/zmap/zlint/lints"
+)
+
+func TestLintNames(t *testing.T) {
+	allowedPrefixes := []string{
+		"n_", // lints.Notice
+		"w_", // lints.Warn
+		"e_", // lints.Error
+	}
+
+	for name := range lints.Lints {
+		var valid bool
+		for _, prefix := range allowedPrefixes {
+			if strings.HasPrefix(name, prefix) {
+				valid = true
+				break
+			}
+		}
+		if !valid {
+			t.Errorf("lint name %q does not start with an allowed prefix (%v)\n",
+				name, allowedPrefixes)
+		}
+	}
+}