diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 55deab9..f06b6d6 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -23,6 +23,7 @@ const ( RPCDefaultPathFlag = "rpc-default-path" OSDevNullFlag = "os-dev-null" SQLIsolationLevelFlag = "sql-isolation-level" + TLSSignatureScheme = "tls-signature-scheme" ) // New returns new usestdlibvars analyzer. @@ -47,6 +48,7 @@ func flags() flag.FlagSet { flags.Bool(RPCDefaultPathFlag, false, "suggest the use of rpc.DefaultXXPath") flags.Bool(OSDevNullFlag, false, "suggest the use of os.DevNull") flags.Bool(SQLIsolationLevelFlag, false, "suggest the use of sql.LevelXX.String()") + flags.Bool(TLSSignatureScheme, false, "suggest the use of tls.SignatureScheme.String()") return *flags } @@ -105,6 +107,10 @@ func run(pass *analysis.Pass) (interface{}, error) { checkSQLIsolationLevel(pass, n) } + if lookupFlag(pass, TLSSignatureScheme) { + checkTLSSignatureScheme(pass, n) + } + case *ast.CompositeLit: typ, ok := n.Type.(*ast.SelectorExpr) if !ok { @@ -417,6 +423,14 @@ func checkSQLIsolationLevel(pass *analysis.Pass, basicLit *ast.BasicLit) { } } +func checkTLSSignatureScheme(pass *analysis.Pass, basicLit *ast.BasicLit) { + currentVal := getBasicLitValue(basicLit) + + if newVal, ok := mapping.TLSSignatureScheme[currentVal]; ok { + report(pass, basicLit.Pos(), currentVal, newVal) + } +} + // getBasicLitFromArgs gets the *ast.BasicLit of a function argument. // // Arguments: diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go index 9c7dd08..9b33acc 100644 --- a/pkg/analyzer/analyzer_test.go +++ b/pkg/analyzer/analyzer_test.go @@ -16,31 +16,26 @@ func TestUseStdlibVars(t *testing.T) { "a/time", "a/os", "a/sql", + "a/tls", } a := analyzer.New() - if err := a.Flags.Set(analyzer.TimeWeekdayFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.TimeMonthFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.TimeLayoutFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.CryptoHashFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.RPCDefaultPathFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.OSDevNullFlag, "true"); err != nil { - t.Error(err) - } - if err := a.Flags.Set(analyzer.SQLIsolationLevelFlag, "true"); err != nil { - t.Error(err) - } + mustNil(t, a.Flags.Set(analyzer.TimeWeekdayFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.TimeMonthFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.TimeLayoutFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.CryptoHashFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.RPCDefaultPathFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.OSDevNullFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.SQLIsolationLevelFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.TLSSignatureScheme, "true")) analysistest.Run(t, analysistest.TestData(), a, pkgs...) } + +func mustNil(t *testing.T, err error) { + t.Helper() + if err != nil { + t.Error(err) + } +} diff --git a/pkg/analyzer/internal/gen.go b/pkg/analyzer/internal/gen.go index 7f343bc..9e5b757 100644 --- a/pkg/analyzer/internal/gen.go +++ b/pkg/analyzer/internal/gen.go @@ -95,6 +95,12 @@ func main() { templateName: "test-template.go.tmpl", fileName: "pkg/analyzer/testdata/src/a/sql/isolationlevel.go", }, + { + mapping: mapping.TLSSignatureScheme, + packageName: "sql_test", + templateName: "test-template.go.tmpl", + fileName: "pkg/analyzer/testdata/src/a/tls/signaturescheme.go", + }, } for _, operation := range operations { diff --git a/pkg/analyzer/internal/mapping/mapping.go b/pkg/analyzer/internal/mapping/mapping.go index c0049cf..ed03274 100644 --- a/pkg/analyzer/internal/mapping/mapping.go +++ b/pkg/analyzer/internal/mapping/mapping.go @@ -2,6 +2,7 @@ package mapping import ( "crypto" + "crypto/tls" "database/sql" "net/http" "net/rpc" @@ -176,3 +177,18 @@ var SQLIsolationLevel = map[string]string{ // sql.LevelSerializable.String(): "sql.LevelSerializable.String()", // sql.LevelLinearizable.String(): "sql.LevelLinearizable.String()", } + +var TLSSignatureScheme = map[string]string{ + tls.PSSWithSHA256.String(): "tls.PSSWithSHA256.String()", + tls.ECDSAWithP256AndSHA256.String(): "tls.ECDSAWithP256AndSHA256.String()", + tls.Ed25519.String(): "tls.Ed25519.String()", + tls.PSSWithSHA384.String(): "tls.PSSWithSHA384.String()", + tls.PSSWithSHA512.String(): "tls.PSSWithSHA512.String()", + tls.PKCS1WithSHA256.String(): "tls.PKCS1WithSHA256.String()", + tls.PKCS1WithSHA384.String(): "tls.PKCS1WithSHA384.String()", + tls.PKCS1WithSHA512.String(): "tls.PKCS1WithSHA512.String()", + tls.ECDSAWithP384AndSHA384.String(): "tls.ECDSAWithP384AndSHA384.String()", + tls.ECDSAWithP521AndSHA512.String(): "tls.ECDSAWithP521AndSHA512.String()", + tls.PKCS1WithSHA1.String(): "tls.PKCS1WithSHA1.String()", + tls.ECDSAWithSHA1.String(): "tls.ECDSAWithSHA1.String()", +} diff --git a/pkg/analyzer/testdata/src/a/tls/signaturescheme.go b/pkg/analyzer/testdata/src/a/tls/signaturescheme.go new file mode 100755 index 0000000..94e1ecb --- /dev/null +++ b/pkg/analyzer/testdata/src/a/tls/signaturescheme.go @@ -0,0 +1,113 @@ +// Code generated by usestdlibvars, DO NOT EDIT. + +package sql_test + +import "fmt" + +var ( + _ = "ECDSAWithP256AndSHA256" // want `"ECDSAWithP256AndSHA256" can be replaced by tls\.ECDSAWithP256AndSHA256\.String\(\)` + _ = "ECDSAWithP384AndSHA384" // want `"ECDSAWithP384AndSHA384" can be replaced by tls\.ECDSAWithP384AndSHA384\.String\(\)` + _ = "ECDSAWithP521AndSHA512" // want `"ECDSAWithP521AndSHA512" can be replaced by tls\.ECDSAWithP521AndSHA512\.String\(\)` + _ = "ECDSAWithSHA1" // want `"ECDSAWithSHA1" can be replaced by tls\.ECDSAWithSHA1\.String\(\)` + _ = "Ed25519" // want `"Ed25519" can be replaced by tls\.Ed25519\.String\(\)` + _ = "PKCS1WithSHA1" // want `"PKCS1WithSHA1" can be replaced by tls\.PKCS1WithSHA1\.String\(\)` + _ = "PKCS1WithSHA256" // want `"PKCS1WithSHA256" can be replaced by tls\.PKCS1WithSHA256\.String\(\)` + _ = "PKCS1WithSHA384" // want `"PKCS1WithSHA384" can be replaced by tls\.PKCS1WithSHA384\.String\(\)` + _ = "PKCS1WithSHA512" // want `"PKCS1WithSHA512" can be replaced by tls\.PKCS1WithSHA512\.String\(\)` + _ = "PSSWithSHA256" // want `"PSSWithSHA256" can be replaced by tls\.PSSWithSHA256\.String\(\)` + _ = "PSSWithSHA384" // want `"PSSWithSHA384" can be replaced by tls\.PSSWithSHA384\.String\(\)` + _ = "PSSWithSHA512" // want `"PSSWithSHA512" can be replaced by tls\.PSSWithSHA512\.String\(\)` +) + +const ( + _ = "ECDSAWithP256AndSHA256" // want `"ECDSAWithP256AndSHA256" can be replaced by tls\.ECDSAWithP256AndSHA256\.String\(\)` + _ = "ECDSAWithP384AndSHA384" // want `"ECDSAWithP384AndSHA384" can be replaced by tls\.ECDSAWithP384AndSHA384\.String\(\)` + _ = "ECDSAWithP521AndSHA512" // want `"ECDSAWithP521AndSHA512" can be replaced by tls\.ECDSAWithP521AndSHA512\.String\(\)` + _ = "ECDSAWithSHA1" // want `"ECDSAWithSHA1" can be replaced by tls\.ECDSAWithSHA1\.String\(\)` + _ = "Ed25519" // want `"Ed25519" can be replaced by tls\.Ed25519\.String\(\)` + _ = "PKCS1WithSHA1" // want `"PKCS1WithSHA1" can be replaced by tls\.PKCS1WithSHA1\.String\(\)` + _ = "PKCS1WithSHA256" // want `"PKCS1WithSHA256" can be replaced by tls\.PKCS1WithSHA256\.String\(\)` + _ = "PKCS1WithSHA384" // want `"PKCS1WithSHA384" can be replaced by tls\.PKCS1WithSHA384\.String\(\)` + _ = "PKCS1WithSHA512" // want `"PKCS1WithSHA512" can be replaced by tls\.PKCS1WithSHA512\.String\(\)` + _ = "PSSWithSHA256" // want `"PSSWithSHA256" can be replaced by tls\.PSSWithSHA256\.String\(\)` + _ = "PSSWithSHA384" // want `"PSSWithSHA384" can be replaced by tls\.PSSWithSHA384\.String\(\)` + _ = "PSSWithSHA512" // want `"PSSWithSHA512" can be replaced by tls\.PSSWithSHA512\.String\(\)` +) + +func _() { + _ = func(s string) string { return s }("ECDSAWithP256AndSHA256") // want `"ECDSAWithP256AndSHA256" can be replaced by tls\.ECDSAWithP256AndSHA256\.String\(\)` + _ = func(s string) string { return s }("text before key ECDSAWithP256AndSHA256") + _ = func(s string) string { return s }("ECDSAWithP256AndSHA256 text after key") + _ = func(s string) string { return s }("ECDSAWithP384AndSHA384") // want `"ECDSAWithP384AndSHA384" can be replaced by tls\.ECDSAWithP384AndSHA384\.String\(\)` + _ = func(s string) string { return s }("text before key ECDSAWithP384AndSHA384") + _ = func(s string) string { return s }("ECDSAWithP384AndSHA384 text after key") + _ = func(s string) string { return s }("ECDSAWithP521AndSHA512") // want `"ECDSAWithP521AndSHA512" can be replaced by tls\.ECDSAWithP521AndSHA512\.String\(\)` + _ = func(s string) string { return s }("text before key ECDSAWithP521AndSHA512") + _ = func(s string) string { return s }("ECDSAWithP521AndSHA512 text after key") + _ = func(s string) string { return s }("ECDSAWithSHA1") // want `"ECDSAWithSHA1" can be replaced by tls\.ECDSAWithSHA1\.String\(\)` + _ = func(s string) string { return s }("text before key ECDSAWithSHA1") + _ = func(s string) string { return s }("ECDSAWithSHA1 text after key") + _ = func(s string) string { return s }("Ed25519") // want `"Ed25519" can be replaced by tls\.Ed25519\.String\(\)` + _ = func(s string) string { return s }("text before key Ed25519") + _ = func(s string) string { return s }("Ed25519 text after key") + _ = func(s string) string { return s }("PKCS1WithSHA1") // want `"PKCS1WithSHA1" can be replaced by tls\.PKCS1WithSHA1\.String\(\)` + _ = func(s string) string { return s }("text before key PKCS1WithSHA1") + _ = func(s string) string { return s }("PKCS1WithSHA1 text after key") + _ = func(s string) string { return s }("PKCS1WithSHA256") // want `"PKCS1WithSHA256" can be replaced by tls\.PKCS1WithSHA256\.String\(\)` + _ = func(s string) string { return s }("text before key PKCS1WithSHA256") + _ = func(s string) string { return s }("PKCS1WithSHA256 text after key") + _ = func(s string) string { return s }("PKCS1WithSHA384") // want `"PKCS1WithSHA384" can be replaced by tls\.PKCS1WithSHA384\.String\(\)` + _ = func(s string) string { return s }("text before key PKCS1WithSHA384") + _ = func(s string) string { return s }("PKCS1WithSHA384 text after key") + _ = func(s string) string { return s }("PKCS1WithSHA512") // want `"PKCS1WithSHA512" can be replaced by tls\.PKCS1WithSHA512\.String\(\)` + _ = func(s string) string { return s }("text before key PKCS1WithSHA512") + _ = func(s string) string { return s }("PKCS1WithSHA512 text after key") + _ = func(s string) string { return s }("PSSWithSHA256") // want `"PSSWithSHA256" can be replaced by tls\.PSSWithSHA256\.String\(\)` + _ = func(s string) string { return s }("text before key PSSWithSHA256") + _ = func(s string) string { return s }("PSSWithSHA256 text after key") + _ = func(s string) string { return s }("PSSWithSHA384") // want `"PSSWithSHA384" can be replaced by tls\.PSSWithSHA384\.String\(\)` + _ = func(s string) string { return s }("text before key PSSWithSHA384") + _ = func(s string) string { return s }("PSSWithSHA384 text after key") + _ = func(s string) string { return s }("PSSWithSHA512") // want `"PSSWithSHA512" can be replaced by tls\.PSSWithSHA512\.String\(\)` + _ = func(s string) string { return s }("text before key PSSWithSHA512") + _ = func(s string) string { return s }("PSSWithSHA512 text after key") +} + +func _() { + _ = fmt.Sprint("ECDSAWithP256AndSHA256") // want `"ECDSAWithP256AndSHA256" can be replaced by tls\.ECDSAWithP256AndSHA256\.String\(\)` + _ = fmt.Sprint("text before key ECDSAWithP256AndSHA256") + _ = fmt.Sprint("ECDSAWithP256AndSHA256 text after key") + _ = fmt.Sprint("ECDSAWithP384AndSHA384") // want `"ECDSAWithP384AndSHA384" can be replaced by tls\.ECDSAWithP384AndSHA384\.String\(\)` + _ = fmt.Sprint("text before key ECDSAWithP384AndSHA384") + _ = fmt.Sprint("ECDSAWithP384AndSHA384 text after key") + _ = fmt.Sprint("ECDSAWithP521AndSHA512") // want `"ECDSAWithP521AndSHA512" can be replaced by tls\.ECDSAWithP521AndSHA512\.String\(\)` + _ = fmt.Sprint("text before key ECDSAWithP521AndSHA512") + _ = fmt.Sprint("ECDSAWithP521AndSHA512 text after key") + _ = fmt.Sprint("ECDSAWithSHA1") // want `"ECDSAWithSHA1" can be replaced by tls\.ECDSAWithSHA1\.String\(\)` + _ = fmt.Sprint("text before key ECDSAWithSHA1") + _ = fmt.Sprint("ECDSAWithSHA1 text after key") + _ = fmt.Sprint("Ed25519") // want `"Ed25519" can be replaced by tls\.Ed25519\.String\(\)` + _ = fmt.Sprint("text before key Ed25519") + _ = fmt.Sprint("Ed25519 text after key") + _ = fmt.Sprint("PKCS1WithSHA1") // want `"PKCS1WithSHA1" can be replaced by tls\.PKCS1WithSHA1\.String\(\)` + _ = fmt.Sprint("text before key PKCS1WithSHA1") + _ = fmt.Sprint("PKCS1WithSHA1 text after key") + _ = fmt.Sprint("PKCS1WithSHA256") // want `"PKCS1WithSHA256" can be replaced by tls\.PKCS1WithSHA256\.String\(\)` + _ = fmt.Sprint("text before key PKCS1WithSHA256") + _ = fmt.Sprint("PKCS1WithSHA256 text after key") + _ = fmt.Sprint("PKCS1WithSHA384") // want `"PKCS1WithSHA384" can be replaced by tls\.PKCS1WithSHA384\.String\(\)` + _ = fmt.Sprint("text before key PKCS1WithSHA384") + _ = fmt.Sprint("PKCS1WithSHA384 text after key") + _ = fmt.Sprint("PKCS1WithSHA512") // want `"PKCS1WithSHA512" can be replaced by tls\.PKCS1WithSHA512\.String\(\)` + _ = fmt.Sprint("text before key PKCS1WithSHA512") + _ = fmt.Sprint("PKCS1WithSHA512 text after key") + _ = fmt.Sprint("PSSWithSHA256") // want `"PSSWithSHA256" can be replaced by tls\.PSSWithSHA256\.String\(\)` + _ = fmt.Sprint("text before key PSSWithSHA256") + _ = fmt.Sprint("PSSWithSHA256 text after key") + _ = fmt.Sprint("PSSWithSHA384") // want `"PSSWithSHA384" can be replaced by tls\.PSSWithSHA384\.String\(\)` + _ = fmt.Sprint("text before key PSSWithSHA384") + _ = fmt.Sprint("PSSWithSHA384 text after key") + _ = fmt.Sprint("PSSWithSHA512") // want `"PSSWithSHA512" can be replaced by tls\.PSSWithSHA512\.String\(\)` + _ = fmt.Sprint("text before key PSSWithSHA512") + _ = fmt.Sprint("PSSWithSHA512 text after key") +}