diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-07-05 09:47:42 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-07-05 10:55:16 +0200 |
| commit | 214e3e269cce39f25d2552d3ba994cced679d5e8 (patch) | |
| tree | e8f0ed5aa35e286f87869d4efde8f01fec6bacc4 /tools | |
| parent | 3940e7a64fa27c338ca1283b8f90143412b281ba (diff) | |
tools/syz-linter: check log/error text starting with capital letter
Update #1876
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/syz-linter/linter.go | 38 | ||||
| -rw-r--r-- | tools/syz-linter/testdata/src/lintertest/lintertest.go | 21 |
2 files changed, 57 insertions, 2 deletions
diff --git a/tools/syz-linter/linter.go b/tools/syz-linter/linter.go index f154706cf..5d09debda 100644 --- a/tools/syz-linter/linter.go +++ b/tools/syz-linter/linter.go @@ -21,6 +21,7 @@ import ( "go/types" "regexp" "strings" + "unicode" "golang.org/x/tools/go/analysis" ) @@ -29,6 +30,10 @@ var AnalyzerPlugin analyzerPlugin type analyzerPlugin struct{} +func main() { + _ = AnalyzerPlugin +} + func (*analyzerPlugin) GetAnalyzers() []*analysis.Analyzer { return []*analysis.Analyzer{ SyzAnalyzer, @@ -52,6 +57,8 @@ func run(pass *analysis.Pass) (interface{}, error) { checkStringLenCompare(pass, n) case *ast.FuncType: checkFuncArgs(pass, n) + case *ast.CallExpr: + checkLogErrorFormat(pass, n) } return true }) @@ -164,6 +171,33 @@ func reportFuncArgs(pass *analysis.Pass, fields []*ast.Field, first, last int) { }) } -func main() { - _ = AnalyzerPlugin +func checkLogErrorFormat(pass *analysis.Pass, n *ast.CallExpr) { + fun, ok := n.Fun.(*ast.SelectorExpr) + if !ok { + return + } + arg := 0 + switch fmt.Sprintf("%v.%v", fun.X, fun.Sel) { + case "log.Print", "log.Printf", "log.Fatal", "log.Fatalf", "fmt.Error", "fmt.Errorf": + arg = 0 + case "log.Logf": + arg = 1 + default: + return + } + lit, ok := n.Args[arg].(*ast.BasicLit) + if !ok || lit.Kind != token.STRING { + return + } + val := lit.Value[1 : len(lit.Value)-1] // the value includes quotes + if len(val) < 2 || !unicode.IsUpper(rune(val[0])) || !unicode.IsLower(rune(val[1])) || + publicIdentifier.MatchString(val) { + return + } + pass.Report(analysis.Diagnostic{ + Pos: n.Pos(), + Message: "bad log/error", + }) } + +var publicIdentifier = regexp.MustCompile(`^[A-Z][[:alnum:]]+(\.[[:alnum:]]+)+ `) diff --git a/tools/syz-linter/testdata/src/lintertest/lintertest.go b/tools/syz-linter/testdata/src/lintertest/lintertest.go index 69b956e80..c44f61683 100644 --- a/tools/syz-linter/testdata/src/lintertest/lintertest.go +++ b/tools/syz-linter/testdata/src/lintertest/lintertest.go @@ -3,6 +3,11 @@ package lintertest +import ( + "fmt" + "log" +) + /* some comment */ // want "Use C-style comments // instead of /* */" var comment = 1 /* some comment */ // want "Use C-style comments // instead of /* */" @@ -42,3 +47,19 @@ func funcArgsBad1() (a int, b int) { // want "Use 'a, b int'" func funcArgsBad2(a int16, b, c uint32, d uint32, e int16) { // want "Use 'b, c, d uint32'" } + +func logErrorMessages() { + fmt.Errorf("good message") + fmt.Errorf("good message %v", 0) + msg := "good message" + fmt.Errorf(msg) + log.Printf("good message") + log.Print("good message") + log.Print("Using.An.Identifier is ok as well") + log.Print(msg) + + fmt.Errorf("Bad message") // want "bad log/error" + log.Fatalf("Bad message %v", 1) // want "bad log/error" + log.Printf("Bad message %v", 1) // want "bad log/error" + log.Print("Bad message") // want "bad log/error" +} |
