Permalink
Browse files

Detect bytes.Equal used to compare net.IP values

Updates gh-64

Idea-By: Filippo Valsorda <hi@filippo.io>
Idea-By: Dmitri Shuralyov <shurcooL@gmail.com>
  • Loading branch information...
1 parent dc8e3f1 commit 9af468716a7b4c40822674b057db7840101575fa @dominikh committed Dec 19, 2016
Showing with 58 additions and 0 deletions.
  1. +1 −0 README.md
  2. +19 −0 lint.go
  3. +19 −0 rules.go
  4. +19 −0 testdata/CheckBytesEqualIP.go
View
@@ -67,6 +67,7 @@ The following things are currently checked by staticcheck:
| SA1018 | `strings.Replace` called with n == 0, which does nothing |
| SA1019 | Using a deprecated function, variable, constant or field |
| SA1020 | Using an invalid `host:port` pair with a `net.Listen`-related function |
+| SA1021 | Using bytes.Equal to compare two net.IP |
| | |
| **SA2???** | **Concurrency issues** |
| SA2000 | `sync.WaitGroup.Add` called inside the goroutine, leading to a race condition |
View
@@ -110,6 +110,7 @@ func (c *Checker) Funcs() map[string]lint.Func {
"SA1018": c.CheckStringsReplaceZero,
"SA1019": c.CheckDeprecated,
"SA1020": c.CheckListenAddress,
+ "SA1021": c.CheckBytesEqualIP,
"SA2000": c.CheckWaitgroupAdd,
"SA2001": c.CheckEmptyCriticalSection,
@@ -2748,3 +2749,21 @@ var checkListenAddressRules = map[string]CallRule{
func (c *Checker) CheckListenAddress(f *lint.File) {
c.checkCalls(f, checkListenAddressRules)
}
+
+var checkBytesEqualIPRules = map[string]CallRule{
+ "bytes.Equal": CallRule{
+ []ArgumentRule{
+ NotChangedTypeFrom{
+ argumentRule{
+ idx: 0,
+ Message: "use net.IP.Equal to compare net.IPs, not bytes.Equal",
+ },
+ "net.IP",
+ },
+ },
+ },
+}
+
+func (c *Checker) CheckBytesEqualIP(f *lint.File) {
+ c.checkCalls(f, checkBytesEqualIPRules)
+}
View
@@ -330,3 +330,22 @@ func (hp ValidHostPort) Validate(v ssa.Value, fn *ssa.Function, c *Checker) erro
}
return nil
}
+
+type NotChangedTypeFrom struct {
+ argumentRule
+ Type string
+}
+
+func (nt NotChangedTypeFrom) Validate(v ssa.Value, fn *ssa.Function, c *Checker) error {
+ change, ok := v.(*ssa.ChangeType)
+ if !ok {
+ return nil
+ }
+ if types.TypeString(change.X.Type(), nil) == nt.Type {
+ if nt.Message != "" {
+ return errors.New(nt.Message)
+ }
+ return fmt.Errorf("shouldn't use function with type %s", nt.Type)
+ }
+ return nil
+}
@@ -0,0 +1,19 @@
+package pkg
+
+import (
+ "bytes"
+ "net"
+)
+
+func fn() {
+ type T []byte
+ var i1, i2 net.IP
+ var b1, b2 []byte
+ var t1, t2 T
+
+ bytes.Equal(i1, i2) // MATCH /use net.IP.Equal to compare net.IPs, not bytes.Equal/
+ bytes.Equal(b1, b2)
+ bytes.Equal(t1, t2)
+
+ // bytes.Equal(i1, b1)
+}

0 comments on commit 9af4687

Please sign in to comment.