diff --git a/.golangci.yml b/.golangci.yml index aa206df8ad..aa879b3d6b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -10,6 +10,14 @@ linters-settings: golint: min-confidence: 0 +issues: + include: + - EXC0006 + - EXC0007 + - EXC0008 + - EXC0009 + - EXC0010 + linters: disable-all: true enable: @@ -23,11 +31,11 @@ linters: - ineffassign - deadcode - typecheck - - golint + - revive - gosec - unconvert - goimports - depguard - prealloc - - scopelint + - exportloopref - whitespace diff --git a/cmd/tidb-dashboard/main.go b/cmd/tidb-dashboard/main.go index d0dce2d02b..03dd1443b1 100644 --- a/cmd/tidb-dashboard/main.go +++ b/cmd/tidb-dashboard/main.go @@ -29,7 +29,7 @@ import ( "fmt" "net" "net/http" - _ "net/http/pprof" //nolint:gosec + _ "net/http/pprof" // #nosec "os" "os/signal" "strings" diff --git a/pkg/apiserver/debugapi/endpoint/endpoint.go b/pkg/apiserver/debugapi/endpoint/endpoint.go index 6600abad21..d12df76016 100644 --- a/pkg/apiserver/debugapi/endpoint/endpoint.go +++ b/pkg/apiserver/debugapi/endpoint/endpoint.go @@ -100,7 +100,7 @@ func (m *APIModel) NewRequest(host string, port int, data map[string]string) (*R return req, nil } -var paramRegexp *regexp.Regexp = regexp.MustCompile(`\{(\w+)\}`) +var paramRegexp = regexp.MustCompile(`\{(\w+)\}`) func populatePath(path string, values Values) (string, error) { var returnErr error diff --git a/pkg/apiserver/diagnose/report.go b/pkg/apiserver/diagnose/report.go index 195ef2c8c8..f65d331f41 100644 --- a/pkg/apiserver/diagnose/report.go +++ b/pkg/apiserver/diagnose/report.go @@ -1483,7 +1483,7 @@ func GetTiKVErrorTable(startTime, endTime string, db *gorm.DB) (TableDef, error) } func GetTiDBCurrentConfig(startTime, endTime string, db *gorm.DB) (TableDef, error) { - sql := fmt.Sprintf("select `key`,`value` from information_schema.CLUSTER_CONFIG where type='tidb' group by `key`,`value` order by `key`;") + sql := "select `key`,`value` from information_schema.CLUSTER_CONFIG where type='tidb' group by `key`,`value` order by `key`;" table := TableDef{ Category: []string{CategoryConfig}, Title: "tidb_current_config", @@ -1499,7 +1499,7 @@ func GetTiDBCurrentConfig(startTime, endTime string, db *gorm.DB) (TableDef, err } func GetPDCurrentConfig(startTime, endTime string, db *gorm.DB) (TableDef, error) { - sql := fmt.Sprintf("select `key`,`value` from information_schema.CLUSTER_CONFIG where type='pd' group by `key`,`value` order by `key`;") + sql := "select `key`,`value` from information_schema.CLUSTER_CONFIG where type='pd' group by `key`,`value` order by `key`;" table := TableDef{ Category: []string{CategoryConfig}, Title: "pd_current_config", @@ -1515,7 +1515,7 @@ func GetPDCurrentConfig(startTime, endTime string, db *gorm.DB) (TableDef, error } func GetTiKVCurrentConfig(startTime, endTime string, db *gorm.DB) (TableDef, error) { - sql := fmt.Sprintf("select `key`,`value` from information_schema.CLUSTER_CONFIG where type='tikv' group by `key`,`value` order by `key`;") + sql := "select `key`,`value` from information_schema.CLUSTER_CONFIG where type='tikv' group by `key`,`value` order by `key`;" table := TableDef{ Category: []string{CategoryConfig}, Title: "tikv_current_config", @@ -2042,7 +2042,7 @@ func GetPDEtcdStatusTable(startTime, endTime string, db *gorm.DB) (TableDef, err } func GetClusterInfoTable(startTime, endTime string, db *gorm.DB) (TableDef, error) { - sql := fmt.Sprintf("select * from information_schema.cluster_info order by type,start_time desc") + sql := "select * from information_schema.cluster_info order by type,start_time desc" table := TableDef{ Category: []string{CategoryHeader}, Title: "cluster_info", @@ -2142,11 +2142,7 @@ func GetClusterHardwareInfoTable(startTime, endTime string, db *gorm.DB) (TableD if !ok { m[s] = &hardWare{s, map[string]int{row[1]: 1}, make(map[string]int), 0, make(map[string]float64), ""} } - if _, ok := m[s].Type[row[1]]; ok { - m[s].Type[row[1]]++ - } else { - m[s].Type[row[1]] = 1 - } + m[s].Type[row[1]]++ if _, ok := m[s].cpu[row[2]]; !ok { m[s].cpu[row[2]] = cpuCnt } diff --git a/pkg/apiserver/info/info.go b/pkg/apiserver/info/info.go index e85eed1b4c..44104e4a82 100644 --- a/pkg/apiserver/info/info.go +++ b/pkg/apiserver/info/info.go @@ -56,7 +56,7 @@ func RegisterRouter(r *gin.RouterGroup, auth *user.AuthService, s *Service) { endpoint.GET("/tables", s.tablesHandler) } -type InfoResponse struct { //nolint:golint +type InfoResponse struct { //nolint Version *version.Info `json:"version"` EnableTelemetry bool `json:"enable_telemetry"` EnableExperimental bool `json:"enable_experimental"` diff --git a/pkg/apiserver/logsearch/task.go b/pkg/apiserver/logsearch/task.go index cb6a1f0208..ce29cc2cce 100644 --- a/pkg/apiserver/logsearch/task.go +++ b/pkg/apiserver/logsearch/task.go @@ -74,7 +74,8 @@ func (tg *TaskGroup) SyncRun() { // Create log directory dir := path.Join(tg.service.logStoreDirectory, strconv.Itoa(int(tg.model.ID))) - if err := os.MkdirAll(dir, 0777); err == nil { + err := os.MkdirAll(dir, 0777) // #nosec + if err == nil { tg.model.LogStoreDir = &dir tg.service.db.Save(tg.model) } @@ -223,7 +224,7 @@ func (t *Task) searchLog(client diagnosticspb.DiagnosticsClient, targetType diag t.setError(err) return } - defer f.Close() + defer f.Close() // #nosec // TODO: Could we use a memory buffer for this and flush the writer regularly to avoid OOM. // This might perform an faster processing. This could also avoid creating an empty .zip @@ -260,7 +261,7 @@ func (t *Task) searchLog(client diagnosticspb.DiagnosticsClient, targetType diag } for _, msg := range res.Messages { line := logMessageToString(msg) - _, err := bufWriter.Write(*(*[]byte)(unsafe.Pointer(&line))) + _, err := bufWriter.Write(*(*[]byte)(unsafe.Pointer(&line))) // #nosec if err != nil { t.setError(err) return diff --git a/pkg/apiserver/profiling/pprof.go b/pkg/apiserver/profiling/pprof.go index 920ab9e227..4f20ceda85 100644 --- a/pkg/apiserver/profiling/pprof.go +++ b/pkg/apiserver/profiling/pprof.go @@ -19,6 +19,7 @@ import ( "io" "io/ioutil" "os" + "path/filepath" "strconv" "sync" "time" @@ -50,7 +51,7 @@ func fetchPprofSVG(op *pprofOptions) (string, error) { return "", fmt.Errorf("failed to get DOT output from file: %v", err) } - b, err := ioutil.ReadFile(f) + b, err := ioutil.ReadFile(filepath.Clean(f)) if err != nil { return "", fmt.Errorf("failed to get DOT output from file: %v", err) } @@ -59,7 +60,7 @@ func fetchPprofSVG(op *pprofOptions) (string, error) { if err != nil { return "", fmt.Errorf("failed to create temp file: %v", err) } - defer tmpfile.Close() + defer tmpfile.Close() // #nosec tmpPath := fmt.Sprintf("%s.%s", tmpfile.Name(), "svg") g := graphviz.New() @@ -87,7 +88,7 @@ func fetchPprof(op *pprofOptions, format string) (string, error) { if err != nil { return "", fmt.Errorf("failed to create temp file: %v", err) } - defer tmpfile.Close() + defer tmpfile.Close() // #nosec tmpPath := fmt.Sprintf("%s.%s", tmpfile.Name(), format) format = "-" + format args := []string{ diff --git a/pkg/apiserver/statement/config.go b/pkg/apiserver/statement/config.go index 409a221d88..2a006a1b70 100644 --- a/pkg/apiserver/statement/config.go +++ b/pkg/apiserver/statement/config.go @@ -35,7 +35,7 @@ func buildGlobalConfigProjectionSelectSQL(config interface{}) string { column := utils.GetGormColumnName(gormTag) return fmt.Sprintf("@@GLOBAL.%s AS %s", column, column), true }, ", ") - return "SELECT " + str //nolint:gosec + return "SELECT " + str // #nosec } // sql will be built like this, @@ -55,7 +55,7 @@ func buildGlobalConfigNamedArgsUpdateSQL(config interface{}, allowedFields ...st column := utils.GetGormColumnName(gormTag) return fmt.Sprintf("@@GLOBAL.%s = @%s", column, f.Name), true }, ", ") - return "SET " + str //nolint:gosec + return "SET " + str // #nosec } func buildStringByStructField(i interface{}, buildFunc func(f reflect.StructField) (string, bool), sep string) string { diff --git a/pkg/apiserver/user/sso/models.go b/pkg/apiserver/user/sso/models.go index b81b27c42f..2843457b4a 100644 --- a/pkg/apiserver/user/sso/models.go +++ b/pkg/apiserver/user/sso/models.go @@ -24,7 +24,7 @@ const ( ImpersonateStatusAuthFail ImpersonateStatus = "auth_fail" ) -type SSOImpersonationModel struct { //nolint:golint +type SSOImpersonationModel struct { //nolint SQLUser string `gorm:"primary_key;size:128" json:"sql_user"` // The encryption key is placed somewhere else in the FS, to avoid being collected by diagnostics collecting tools. EncryptedPass string `gorm:"type:text" json:"-"` diff --git a/pkg/apiserver/user/sso/service.go b/pkg/apiserver/user/sso/service.go index 9498b4b37b..ab6f557479 100644 --- a/pkg/apiserver/user/sso/service.go +++ b/pkg/apiserver/user/sso/service.go @@ -247,8 +247,9 @@ func (s *Service) createImpersonation(user string, password string) (*SSOImperso } func (s *Service) revokeAllImpersonations() error { + sqlStr := fmt.Sprintf("DELETE FROM `%s`", SSOImpersonationModel{}.TableName()) // #nosec return s.params.LocalStore. - Exec(fmt.Sprintf("DELETE FROM `%s`", SSOImpersonationModel{}.TableName())). //nolint:gosec + Exec(sqlStr). Error } diff --git a/pkg/apiserver/utils/export.go b/pkg/apiserver/utils/export.go index e7ba1d451f..2f24f80d92 100644 --- a/pkg/apiserver/utils/export.go +++ b/pkg/apiserver/utils/export.go @@ -8,6 +8,7 @@ import ( "io" "io/ioutil" "os" + "path/filepath" "reflect" "strings" "time" @@ -75,7 +76,7 @@ func ExportCSV(data [][]string, filename, tokenNamespace string) (token string, if err != nil { return } - defer csvFile.Close() + defer csvFile.Close() // #nosec // generate encryption key secretKey := *cryptopasta.NewEncryptionKey() @@ -84,7 +85,7 @@ func ExportCSV(data [][]string, filename, tokenNamespace string) (token string, go func() { csvwriter := csv.NewWriter(pw) _ = csvwriter.WriteAll(data) - pw.Close() + _ = pw.Close() }() err = aesctr.Encrypt(pr, csvFile, secretKey[0:16], secretKey[16:]) if err != nil { @@ -121,7 +122,7 @@ func DownloadByToken(token, tokenNamespace string, c *gin.Context) { _ = c.Error(err) return } - f, err := os.Open(filePath) + f, err := os.Open(filepath.Clean(filePath)) if err != nil { _ = c.Error(err) return @@ -134,6 +135,6 @@ func DownloadByToken(token, tokenNamespace string, c *gin.Context) { log.Error("decrypt csv failed", zap.Error(err)) } // delete it anyway - f.Close() + _ = f.Close() _ = os.Remove(filePath) } diff --git a/pkg/apiserver/utils/fs_stream.go b/pkg/apiserver/utils/fs_stream.go index 0169af9b56..72b11ac49d 100644 --- a/pkg/apiserver/utils/fs_stream.go +++ b/pkg/apiserver/utils/fs_stream.go @@ -93,8 +93,8 @@ func FSServe(c *gin.Context, token string, requiredIssuer string) { } return } - defer file.Close() //nolint:errcheck - defer os.Remove(tokenBody.TempFileName) //nolint:errcheck + defer file.Close() // #nosec + defer os.Remove(tokenBody.TempFileName) // #nosec key, err := hex.DecodeString(tokenBody.TempFileKeyInHex) if err != nil { diff --git a/pkg/apiserver/utils/zip.go b/pkg/apiserver/utils/zip.go index db881511f4..bb5a556f15 100644 --- a/pkg/apiserver/utils/zip.go +++ b/pkg/apiserver/utils/zip.go @@ -17,6 +17,7 @@ import ( "archive/zip" "io" "os" + "path/filepath" ) func StreamZipPack(w io.Writer, files []string, needCompress bool) error { @@ -34,11 +35,11 @@ func StreamZipPack(w io.Writer, files []string, needCompress bool) error { } func streamZipFile(zipPack *zip.Writer, file string, needCompress bool) error { - f, err := os.Open(file) + f, err := os.Open(filepath.Clean(file)) if err != nil { return err } - defer f.Close() + defer f.Close() // #nosec fileInfo, err := f.Stat() if err != nil { diff --git a/pkg/dbstore/dbstore.go b/pkg/dbstore/dbstore.go index 6f4a45518a..3fd1388d6c 100644 --- a/pkg/dbstore/dbstore.go +++ b/pkg/dbstore/dbstore.go @@ -35,7 +35,8 @@ type DB struct { } func NewDBStore(lc fx.Lifecycle, config *config.Config) (*DB, error) { - if err := os.MkdirAll(config.DataDir, 0777); err != nil { + err := os.MkdirAll(config.DataDir, 0777) // #nosec + if err != nil { log.Error("Failed to create Dashboard storage directory", zap.Error(err)) return nil, err } diff --git a/pkg/keyvisual/input/file.go b/pkg/keyvisual/input/file.go index bfcf2d2c36..c6d646bba9 100644 --- a/pkg/keyvisual/input/file.go +++ b/pkg/keyvisual/input/file.go @@ -17,6 +17,7 @@ import ( "context" "io/ioutil" "os" + "path/filepath" "time" "github.com/pingcap/log" @@ -60,11 +61,11 @@ func (input *fileInput) Background(ctx context.Context, stat *storage.Stat) { func readFile(fileTime time.Time) (*RegionsInfo, error) { fileName := fileTime.Format("./data/20060102-15-04.json") - file, err := os.Open(fileName) + file, err := os.Open(filepath.Clean(fileName)) if err != nil { return nil, ErrInvalidData.Wrap(err, "%s regions API unmarshal failed, from file %s", distro.Data("pd"), fileName) } - defer file.Close() + defer file.Close() // #nosec data, err := ioutil.ReadAll(file) if err != nil { return nil, ErrInvalidData.Wrap(err, "%s regions API unmarshal failed, from file %s", distro.Data("pd"), fileName) diff --git a/pkg/keyvisual/matrix/axis.go b/pkg/keyvisual/matrix/axis.go index a8c4896857..47062ef7ce 100644 --- a/pkg/keyvisual/matrix/axis.go +++ b/pkg/keyvisual/matrix/axis.go @@ -197,7 +197,7 @@ func (c *chunk) Reduce(newKeys []string) chunk { // GetFocusRows estimates the number of rows generated by executing a Focus with a specified threshold func (c *chunk) GetFocusRows(threshold uint64) (count int) { start := 0 - var bucketSum uint64 = 0 + var bucketSum uint64 generateBucket := func(end int) { if end > start { count++ @@ -226,7 +226,7 @@ func (c *chunk) Focus(labeler decorator.Labeler, threshold uint64, ratio int, ta newKeys = append(newKeys, c.Keys[0]) start := 0 - var bucketSum uint64 = 0 + var bucketSum uint64 generateBucket := func(end int) { if end > start { newKeys = append(newKeys, c.Keys[end]) @@ -263,7 +263,7 @@ func (c *chunk) MergeColdLogicalRange(labeler decorator.Labeler, threshold uint6 coldStart := 0 coldEnd := 0 - var coldRangeSum uint64 = 0 + var coldRangeSum uint64 mergeColdRange := func() { if coldEnd <= coldStart { return @@ -277,7 +277,7 @@ func (c *chunk) MergeColdLogicalRange(labeler decorator.Labeler, threshold uint6 if end <= coldEnd { return } - var rangeSum uint64 = 0 + var rangeSum uint64 for i := coldEnd; i < end; i++ { rangeSum += c.Values[i] } diff --git a/pkg/keyvisual/matrix/distance_test.go b/pkg/keyvisual/matrix/distance_test.go index da46c1c3ce..baa726ca34 100644 --- a/pkg/keyvisual/matrix/distance_test.go +++ b/pkg/keyvisual/matrix/distance_test.go @@ -47,7 +47,9 @@ func BenchmarkGenerateScale(b *testing.B) { var data testDisData fin, err := os.Open("../testdata/dis.json.gzip") perr(err) - defer fin.Close() + defer func() { + _ = fin.Close() + }() ifs, err := gzip.NewReader(fin) perr(err) err = json.NewDecoder(ifs).Decode(&data) diff --git a/pkg/keyvisual/matrix/key.go b/pkg/keyvisual/matrix/key.go index af6faf2612..a985171b0c 100644 --- a/pkg/keyvisual/matrix/key.go +++ b/pkg/keyvisual/matrix/key.go @@ -40,7 +40,7 @@ func (km *KeyMap) SaveKeys(keys []string) { } func equal(keyA, keyB string) bool { - pA := (*reflect.StringHeader)(unsafe.Pointer(&keyA)) - pB := (*reflect.StringHeader)(unsafe.Pointer(&keyB)) + pA := (*reflect.StringHeader)(unsafe.Pointer(&keyA)) // #nosec + pB := (*reflect.StringHeader)(unsafe.Pointer(&keyB)) // #nosec return pA.Data == pB.Data && pA.Len == pB.Len } diff --git a/pkg/keyvisual/region/utils.go b/pkg/keyvisual/region/utils.go index ea0fc179a0..e28743a5c0 100644 --- a/pkg/keyvisual/region/utils.go +++ b/pkg/keyvisual/region/utils.go @@ -23,8 +23,8 @@ func String(b []byte) (s string) { if len(b) == 0 { return "" } - pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) // #nosec + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) // #nosec pstring.Data = pbytes.Data pstring.Len = pbytes.Len return @@ -35,8 +35,8 @@ func Bytes(s string) (b []byte) { if len(s) == 0 { return } - pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) // #nosec + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) // #nosec pbytes.Data = pstring.Data pbytes.Len = pstring.Len pbytes.Cap = pstring.Len diff --git a/pkg/keyvisual/storage/model_test.go b/pkg/keyvisual/storage/model_test.go index 48fbe0ebb3..14d3a1a3a2 100644 --- a/pkg/keyvisual/storage/model_test.go +++ b/pkg/keyvisual/storage/model_test.go @@ -91,7 +91,7 @@ func (t *testDbstoreSuite) TestAxisModelFunc(c *C) { if err != nil { c.Fatalf("Create table AxisModel error: %v", err) } - var layerNum uint8 = 0 + var layerNum uint8 endTime := time.Now() axis := matrix.Axis{ Keys: []string{"a", "b"}, diff --git a/pkg/tidb/proxy.go b/pkg/tidb/proxy.go index 3850cb6f06..f12129a5d4 100644 --- a/pkg/tidb/proxy.go +++ b/pkg/tidb/proxy.go @@ -31,7 +31,7 @@ func (r *remote) checkAlive(timeout time.Duration) error { if err != nil { return err } - conn.Close() + _ = conn.Close() r.inactive.Store(false) return nil } @@ -105,20 +105,20 @@ func (p *proxy) serve(in net.Conn) { out := p.pickActiveConn() if out == nil { log.Warn("no alive remote, drop incoming conn") - in.Close() + _ = in.Close() return } // bidirectional copy go func() { //nolint io.Copy(in, out) - in.Close() - out.Close() + _ = in.Close() + _ = out.Close() }() //nolint io.Copy(out, in) - out.Close() - in.Close() + _ = out.Close() + _ = in.Close() } func (p *proxy) pickActiveConn() (out net.Conn) { diff --git a/scripts/lint.sh b/scripts/lint.sh index 568969660a..6b2af2f915 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -10,7 +10,7 @@ PROJECT_DIR="$(dirname "$DIR")" cd $PROJECT_DIR LINT_BIN=./bin/golangci-lint -REQUIRED_VERSION=1.23.8 +REQUIRED_VERSION=1.42.0 NEED_DOWNLOAD=true echo "+ Check golangci-lint binary" diff --git a/tools/distro_info_generate/main.go b/tools/distro_info_generate/main.go index 25a49731f0..82faf20fc8 100644 --- a/tools/distro_info_generate/main.go +++ b/tools/distro_info_generate/main.go @@ -33,7 +33,7 @@ func main() { if err != nil { log.Fatalln(zap.Error(err)) } - if err := ioutil.WriteFile(*outputPath, d, 0666); err != nil { + if err := ioutil.WriteFile(*outputPath, d, 0600); err != nil { log.Fatalln(zap.Error(err)) } }