aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/polyfloyd
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-09-10 12:16:33 +0200
committerTaras Madan <tarasmadan@google.com>2024-09-10 14:05:26 +0000
commitc97c816133b42257d0bcf1ee4bd178bb2a7a2b9e (patch)
tree0bcbc2e540bbf8f62f6c17887cdd53b8c2cee637 /vendor/github.com/polyfloyd
parent54e657429ab892ad06c90cd7c1a4eb33ba93a3dc (diff)
vendor: update
Diffstat (limited to 'vendor/github.com/polyfloyd')
-rw-r--r--vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go187
-rw-r--r--vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go35
-rw-r--r--vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go56
-rw-r--r--vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go15
4 files changed, 175 insertions, 118 deletions
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go
index 8bfb4c9b2..cf481708a 100644
--- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go
@@ -7,106 +7,135 @@ import (
"strings"
)
-var allowedErrors = []struct {
- err string
- fun string
-}{
- // pkg/archive/tar
- {err: "io.EOF", fun: "(*archive/tar.Reader).Next"},
- {err: "io.EOF", fun: "(*archive/tar.Reader).Read"},
- // pkg/bufio
- {err: "io.EOF", fun: "(*bufio.Reader).Discard"},
- {err: "io.EOF", fun: "(*bufio.Reader).Peek"},
- {err: "io.EOF", fun: "(*bufio.Reader).Read"},
- {err: "io.EOF", fun: "(*bufio.Reader).ReadByte"},
- {err: "io.EOF", fun: "(*bufio.Reader).ReadBytes"},
- {err: "io.EOF", fun: "(*bufio.Reader).ReadLine"},
- {err: "io.EOF", fun: "(*bufio.Reader).ReadSlice"},
- {err: "io.EOF", fun: "(*bufio.Reader).ReadString"},
- {err: "io.EOF", fun: "(*bufio.Scanner).Scan"},
- // pkg/bytes
- {err: "io.EOF", fun: "(*bytes.Buffer).Read"},
- {err: "io.EOF", fun: "(*bytes.Buffer).ReadByte"},
- {err: "io.EOF", fun: "(*bytes.Buffer).ReadBytes"},
- {err: "io.EOF", fun: "(*bytes.Buffer).ReadRune"},
- {err: "io.EOF", fun: "(*bytes.Buffer).ReadString"},
- {err: "io.EOF", fun: "(*bytes.Reader).Read"},
- {err: "io.EOF", fun: "(*bytes.Reader).ReadAt"},
- {err: "io.EOF", fun: "(*bytes.Reader).ReadByte"},
- {err: "io.EOF", fun: "(*bytes.Reader).ReadRune"},
- {err: "io.EOF", fun: "(*bytes.Reader).ReadString"},
- // pkg/database/sql
- {err: "database/sql.ErrNoRows", fun: "(*database/sql.Row).Scan"},
- // pkg/debug/elf
- {err: "io.EOF", fun: "debug/elf.Open"},
- {err: "io.EOF", fun: "debug/elf.NewFile"},
- // pkg/io
- {err: "io.EOF", fun: "(io.ReadCloser).Read"},
- {err: "io.EOF", fun: "(io.Reader).Read"},
- {err: "io.EOF", fun: "(io.ReaderAt).ReadAt"},
- {err: "io.EOF", fun: "(*io.LimitedReader).Read"},
- {err: "io.EOF", fun: "(*io.SectionReader).Read"},
- {err: "io.EOF", fun: "(*io.SectionReader).ReadAt"},
- {err: "io.ErrClosedPipe", fun: "(*io.PipeWriter).Write"},
- {err: "io.ErrShortBuffer", fun: "io.ReadAtLeast"},
- {err: "io.ErrUnexpectedEOF", fun: "io.ReadAtLeast"},
- {err: "io.EOF", fun: "io.ReadFull"},
- {err: "io.ErrUnexpectedEOF", fun: "io.ReadFull"},
- // pkg/net/http
- {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServe"},
- {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServeTLS"},
- {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).Serve"},
- {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ServeTLS"},
- {err: "net/http.ErrServerClosed", fun: "net/http.ListenAndServe"},
- {err: "net/http.ErrServerClosed", fun: "net/http.ListenAndServeTLS"},
- {err: "net/http.ErrServerClosed", fun: "net/http.Serve"},
- {err: "net/http.ErrServerClosed", fun: "net/http.ServeTLS"},
- // pkg/os
- {err: "io.EOF", fun: "(*os.File).Read"},
- {err: "io.EOF", fun: "(*os.File).ReadAt"},
- {err: "io.EOF", fun: "(*os.File).ReadDir"},
- {err: "io.EOF", fun: "(*os.File).Readdir"},
- {err: "io.EOF", fun: "(*os.File).Readdirnames"},
- // pkg/strings
- {err: "io.EOF", fun: "(*strings.Reader).Read"},
- {err: "io.EOF", fun: "(*strings.Reader).ReadAt"},
- {err: "io.EOF", fun: "(*strings.Reader).ReadByte"},
- {err: "io.EOF", fun: "(*strings.Reader).ReadRune"},
- // pkg/context
- {err: "context.DeadlineExceeded", fun: "(context.Context).Err"},
- {err: "context.Canceled", fun: "(context.Context).Err"},
+type AllowPair struct {
+ Err string
+ Fun string
}
-var allowedErrorWildcards = []struct {
- err string
- fun string
-}{
+var allowedErrorsMap = make(map[string]map[string]struct{})
+
+func setDefaultAllowedErrors() {
+ allowedMapAppend([]AllowPair{
+ // pkg/archive/tar
+ {Err: "io.EOF", Fun: "(*archive/tar.Reader).Next"},
+ {Err: "io.EOF", Fun: "(*archive/tar.Reader).Read"},
+ // pkg/bufio
+ {Err: "io.EOF", Fun: "(*bufio.Reader).Discard"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).Peek"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).Read"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).ReadByte"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).ReadBytes"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).ReadLine"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).ReadSlice"},
+ {Err: "io.EOF", Fun: "(*bufio.Reader).ReadString"},
+ {Err: "io.EOF", Fun: "(*bufio.Scanner).Scan"},
+ // pkg/bytes
+ {Err: "io.EOF", Fun: "(*bytes.Buffer).Read"},
+ {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadByte"},
+ {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadBytes"},
+ {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadRune"},
+ {Err: "io.EOF", Fun: "(*bytes.Buffer).ReadString"},
+ {Err: "io.EOF", Fun: "(*bytes.Reader).Read"},
+ {Err: "io.EOF", Fun: "(*bytes.Reader).ReadAt"},
+ {Err: "io.EOF", Fun: "(*bytes.Reader).ReadByte"},
+ {Err: "io.EOF", Fun: "(*bytes.Reader).ReadRune"},
+ {Err: "io.EOF", Fun: "(*bytes.Reader).ReadString"},
+ // pkg/database/sql
+ {Err: "database/sql.ErrNoRows", Fun: "(*database/sql.Row).Scan"},
+ // pkg/debug/elf
+ {Err: "io.EOF", Fun: "debug/elf.Open"},
+ {Err: "io.EOF", Fun: "debug/elf.NewFile"},
+ // pkg/io
+ {Err: "io.EOF", Fun: "(io.ReadCloser).Read"},
+ {Err: "io.EOF", Fun: "(io.Reader).Read"},
+ {Err: "io.EOF", Fun: "(io.ReaderAt).ReadAt"},
+ {Err: "io.EOF", Fun: "(*io.LimitedReader).Read"},
+ {Err: "io.EOF", Fun: "(*io.SectionReader).Read"},
+ {Err: "io.EOF", Fun: "(*io.SectionReader).ReadAt"},
+ {Err: "io.ErrClosedPipe", Fun: "(*io.PipeWriter).Write"},
+ {Err: "io.ErrShortBuffer", Fun: "io.ReadAtLeast"},
+ {Err: "io.ErrUnexpectedEOF", Fun: "io.ReadAtLeast"},
+ {Err: "io.EOF", Fun: "io.ReadFull"},
+ {Err: "io.ErrUnexpectedEOF", Fun: "io.ReadFull"},
+ // pkg/mime
+ {Err: "mime.ErrInvalidMediaParameter", Fun: "mime.ParseMediaType"},
+ // pkg/net/http
+ {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ListenAndServe"},
+ {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ListenAndServeTLS"},
+ {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).Serve"},
+ {Err: "net/http.ErrServerClosed", Fun: "(*net/http.Server).ServeTLS"},
+ {Err: "net/http.ErrServerClosed", Fun: "net/http.ListenAndServe"},
+ {Err: "net/http.ErrServerClosed", Fun: "net/http.ListenAndServeTLS"},
+ {Err: "net/http.ErrServerClosed", Fun: "net/http.Serve"},
+ {Err: "net/http.ErrServerClosed", Fun: "net/http.ServeTLS"},
+ // pkg/os
+ {Err: "io.EOF", Fun: "(*os.File).Read"},
+ {Err: "io.EOF", Fun: "(*os.File).ReadAt"},
+ {Err: "io.EOF", Fun: "(*os.File).ReadDir"},
+ {Err: "io.EOF", Fun: "(*os.File).Readdir"},
+ {Err: "io.EOF", Fun: "(*os.File).Readdirnames"},
+ // pkg/strings
+ {Err: "io.EOF", Fun: "(*strings.Reader).Read"},
+ {Err: "io.EOF", Fun: "(*strings.Reader).ReadAt"},
+ {Err: "io.EOF", Fun: "(*strings.Reader).ReadByte"},
+ {Err: "io.EOF", Fun: "(*strings.Reader).ReadRune"},
+ // pkg/context
+ {Err: "context.DeadlineExceeded", Fun: "(context.Context).Err"},
+ {Err: "context.Canceled", Fun: "(context.Context).Err"},
+ // pkg/encoding/json
+ {Err: "io.EOF", Fun: "(*encoding/json.Decoder).Decode"},
+ // pkg/encoding/csv
+ {Err: "io.EOF", Fun: "(*encoding/csv.Reader).Read"},
+ // pkg/mime/multipart
+ {Err: "io.EOF", Fun: "(*mime/multipart.Reader).NextPart"},
+ {Err: "io.EOF", Fun: "(*mime/multipart.Reader).NextRawPart"},
+ {Err: "mime/multipart.ErrMessageTooLarge", Fun: "(*mime/multipart.Reader).ReadForm"},
+ })
+}
+
+func allowedMapAppend(ap []AllowPair) {
+ for _, pair := range ap {
+ if _, ok := allowedErrorsMap[pair.Err]; !ok {
+ allowedErrorsMap[pair.Err] = make(map[string]struct{})
+ }
+ allowedErrorsMap[pair.Err][pair.Fun] = struct{}{}
+ }
+}
+
+var allowedErrorWildcards = []AllowPair{
+ // pkg/syscall
+ {Err: "syscall.E", Fun: "syscall."},
// golang.org/x/sys/unix
- {err: "golang.org/x/sys/unix.E", fun: "golang.org/x/sys/unix."},
+ {Err: "golang.org/x/sys/unix.E", Fun: "golang.org/x/sys/unix."},
+}
+
+func allowedWildcardAppend(ap []AllowPair) {
+ allowedErrorWildcards = append(allowedErrorWildcards, ap...)
}
func isAllowedErrAndFunc(err, fun string) bool {
- for _, allow := range allowedErrorWildcards {
- if strings.HasPrefix(fun, allow.fun) && strings.HasPrefix(err, allow.err) {
+ if allowedFuncs, allowErr := allowedErrorsMap[err]; allowErr {
+ if _, allow := allowedFuncs[fun]; allow {
return true
}
}
- for _, allow := range allowedErrors {
- if allow.fun == fun && allow.err == err {
+ for _, allow := range allowedErrorWildcards {
+ if strings.HasPrefix(fun, allow.Fun) && strings.HasPrefix(err, allow.Err) {
return true
}
}
+
return false
}
-func isAllowedErrorComparison(pass *TypesInfoExt, binExpr *ast.BinaryExpr) bool {
+func isAllowedErrorComparison(pass *TypesInfoExt, a, b ast.Expr) bool {
var errName string // `<package>.<name>`, e.g. `io.EOF`
var callExprs []*ast.CallExpr
// Figure out which half of the expression is the returned error and which
// half is the presumed error declaration.
- for _, expr := range []ast.Expr{binExpr.X, binExpr.Y} {
+ for _, expr := range []ast.Expr{a, b} {
switch t := expr.(type) {
case *ast.SelectorExpr:
// A selector which we assume refers to a staticaly declared error
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
index f034913ea..84ebd6cf8 100644
--- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go
@@ -1,7 +1,6 @@
package errorlint
import (
- "flag"
"go/ast"
"go/types"
"sort"
@@ -9,32 +8,36 @@ import (
"golang.org/x/tools/go/analysis"
)
-func NewAnalyzer() *analysis.Analyzer {
- return &analysis.Analyzer{
- Name: "errorlint",
- Doc: "Source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.",
- Run: run,
- Flags: flagSet,
+func NewAnalyzer(opts ...Option) *analysis.Analyzer {
+ for _, o := range opts {
+ o()
}
+
+ setDefaultAllowedErrors()
+
+ a := &analysis.Analyzer{
+ Name: "errorlint",
+ Doc: "Source code linter for Go software that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.",
+ Run: run,
+ }
+
+ a.Flags.BoolVar(&checkComparison, "comparison", true, "Check for plain error comparisons")
+ a.Flags.BoolVar(&checkAsserts, "asserts", true, "Check for plain type assertions and type switches")
+ a.Flags.BoolVar(&checkErrorf, "errorf", false, "Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats")
+ a.Flags.BoolVar(&checkErrorfMulti, "errorf-multi", true, "Permit more than 1 %w verb, valid per Go 1.20 (Requires -errorf=true)")
+
+ return a
}
var (
- flagSet flag.FlagSet
checkComparison bool
checkAsserts bool
checkErrorf bool
checkErrorfMulti bool
)
-func init() {
- flagSet.BoolVar(&checkComparison, "comparison", true, "Check for plain error comparisons")
- flagSet.BoolVar(&checkAsserts, "asserts", true, "Check for plain type assertions and type switches")
- flagSet.BoolVar(&checkErrorf, "errorf", false, "Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats")
- flagSet.BoolVar(&checkErrorfMulti, "errorf-multi", true, "Permit more than 1 %w verb, valid per Go 1.20 (Requires -errorf=true)")
-}
-
func run(pass *analysis.Pass) (interface{}, error) {
- lints := []analysis.Diagnostic{}
+ var lints []analysis.Diagnostic
extInfo := newTypesInfoExt(pass)
if checkComparison {
l := LintErrorComparisons(extInfo)
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
index 572a3816d..9ac465c65 100644
--- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go
@@ -20,7 +20,8 @@ func (l ByPosition) Less(i, j int) bool {
}
func LintFmtErrorfCalls(fset *token.FileSet, info types.Info, multipleWraps bool) []analysis.Diagnostic {
- lints := []analysis.Diagnostic{}
+ var lints []analysis.Diagnostic
+
for expr, t := range info.Types {
// Search for error expressions that are the result of fmt.Errorf
// invocations.
@@ -159,7 +160,7 @@ func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) {
}
func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
- lints := []analysis.Diagnostic{}
+ var lints []analysis.Diagnostic
for expr := range info.TypesInfo.Types {
// Find == and != operations.
@@ -171,15 +172,15 @@ func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
continue
}
// Comparing errors with nil is okay.
- if isNilComparison(binExpr) {
+ if isNil(binExpr.X) || isNil(binExpr.Y) {
continue
}
// Find comparisons of which one side is a of type error.
- if !isErrorComparison(info.TypesInfo, binExpr) {
+ if !isErrorType(info.TypesInfo, binExpr.X) && !isErrorType(info.TypesInfo, binExpr.Y) {
continue
}
// Some errors that are returned from some functions are exempt.
- if isAllowedErrorComparison(info, binExpr) {
+ if isAllowedErrorComparison(info, binExpr.X, binExpr.Y) {
continue
}
// Comparisons that happen in `func (type) Is(error) bool` are okay.
@@ -200,13 +201,29 @@ func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
continue
}
// Check whether the switch operates on an error type.
- if switchStmt.Tag == nil {
+ if !isErrorType(info.TypesInfo, switchStmt.Tag) {
continue
}
- tagType := info.TypesInfo.Types[switchStmt.Tag]
- if tagType.Type.String() != "error" {
+
+ var problematicCaseClause *ast.CaseClause
+ outer:
+ for _, stmt := range switchStmt.Body.List {
+ caseClause := stmt.(*ast.CaseClause)
+ for _, caseExpr := range caseClause.List {
+ if isNil(caseExpr) {
+ continue
+ }
+ // Some errors that are returned from some functions are exempt.
+ if !isAllowedErrorComparison(info, switchStmt.Tag, caseExpr) {
+ problematicCaseClause = caseClause
+ break outer
+ }
+ }
+ }
+ if problematicCaseClause == nil {
continue
}
+ // Comparisons that happen in `func (type) Is(error) bool` are okay.
if isNodeInErrorIsFunc(info, switchStmt) {
continue
}
@@ -214,29 +231,22 @@ func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic {
if switchComparesNonNil(switchStmt) {
lints = append(lints, analysis.Diagnostic{
Message: "switch on an error will fail on wrapped errors. Use errors.Is to check for specific errors",
- Pos: switchStmt.Pos(),
+ Pos: problematicCaseClause.Pos(),
})
}
-
}
return lints
}
-func isNilComparison(binExpr *ast.BinaryExpr) bool {
- if ident, ok := binExpr.X.(*ast.Ident); ok && ident.Name == "nil" {
- return true
- }
- if ident, ok := binExpr.Y.(*ast.Ident); ok && ident.Name == "nil" {
- return true
- }
- return false
+func isNil(ex ast.Expr) bool {
+ ident, ok := ex.(*ast.Ident)
+ return ok && ident.Name == "nil"
}
-func isErrorComparison(info *types.Info, binExpr *ast.BinaryExpr) bool {
- tx := info.Types[binExpr.X]
- ty := info.Types[binExpr.Y]
- return tx.Type.String() == "error" || ty.Type.String() == "error"
+func isErrorType(info *types.Info, ex ast.Expr) bool {
+ t := info.Types[ex].Type
+ return t != nil && t.String() == "error"
}
func isNodeInErrorIsFunc(info *TypesInfoExt, node ast.Node) bool {
@@ -289,7 +299,7 @@ func switchComparesNonNil(switchStmt *ast.SwitchStmt) bool {
}
func LintErrorTypeAssertions(fset *token.FileSet, info *TypesInfoExt) []analysis.Diagnostic {
- lints := []analysis.Diagnostic{}
+ var lints []analysis.Diagnostic
for expr := range info.TypesInfo.Types {
// Find type assertions.
diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go
new file mode 100644
index 000000000..4d7c742d8
--- /dev/null
+++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/options.go
@@ -0,0 +1,15 @@
+package errorlint
+
+type Option func()
+
+func WithAllowedErrors(ap []AllowPair) Option {
+ return func() {
+ allowedMapAppend(ap)
+ }
+}
+
+func WithAllowedWildcard(ap []AllowPair) Option {
+ return func() {
+ allowedWildcardAppend(ap)
+ }
+}