Files
odidere/vendor/honnef.co/go/tools/staticcheck/sa1021/sa1021.go
2026-06-06 01:17:29 +00:00

50 lines
1.6 KiB
Go

package sa1021
import (
"go/types"
"honnef.co/go/tools/analysis/callcheck"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/go/ir"
"honnef.co/go/tools/internal/passes/buildir"
"honnef.co/go/tools/knowledge"
"golang.org/x/tools/go/analysis"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1021",
Requires: []*analysis.Analyzer{buildir.Analyzer},
Run: callcheck.Analyzer(rules),
},
Doc: &lint.RawDocumentation{
Title: `Using \'bytes.Equal\' to compare two \'net.IP\'`,
Text: `A \'net.IP\' stores an IPv4 or IPv6 address as a slice of bytes. The
length of the slice for an IPv4 address, however, can be either 4 or
16 bytes long, using different ways of representing IPv4 addresses. In
order to correctly compare two \'net.IP\'s, the \'net.IP.Equal\' method should
be used, as it takes both representations into account.`,
Since: "2017.1",
Severity: lint.SeverityWarning,
MergeIf: lint.MergeIfAny,
},
})
var Analyzer = SCAnalyzer.Analyzer
var rules = map[string]callcheck.Check{
"bytes.Equal": func(call *callcheck.Call) {
if isConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.a")].Value, "net.IP") &&
isConvertedFrom(call.Args[knowledge.Arg("bytes.Equal.b")].Value, "net.IP") {
call.Invalid("use net.IP.Equal to compare net.IPs, not bytes.Equal")
}
},
}
// ConvertedFrom reports whether value v was converted from type typ.
func isConvertedFrom(v callcheck.Value, typ string) bool {
change, ok := v.Value.(*ir.ChangeType)
return ok && types.TypeString(types.Unalias(change.X.Type()), nil) == typ
}