Skip to content

Commit

Permalink
checkers: add filepath.Join checker (#930)
Browse files Browse the repository at this point in the history
Reports filepath.Join() string literal arguments that contain
'/' or '\' as it kinda defeats the purpose of using that function.

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
  • Loading branch information
quasilyte committed May 26, 2020
1 parent 870cf89 commit 9ac4766
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
50 changes: 50 additions & 0 deletions checkers/filepathJoin_checker.go
@@ -0,0 +1,50 @@
package checkers

import (
"go/ast"
"strings"

"github.com/go-lintpack/lintpack"
"github.com/go-lintpack/lintpack/astwalk"
"github.com/go-toolsmith/astcast"
)

func init() {
var info lintpack.CheckerInfo
info.Name = "filepathJoin"
info.Tags = []string{"diagnostic", "experimental"}
info.Summary = "Detects problems in filepath.Join() function calls"
info.Before = `filepath.Join("dir/", filename)`
info.After = `filepath.Join("dir", filename)`

collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker {
return astwalk.WalkerForExpr(&filepathJoinChecker{ctx: ctx})
})
}

type filepathJoinChecker struct {
astwalk.WalkHandler
ctx *lintpack.CheckerContext
}

func (c *filepathJoinChecker) VisitExpr(expr ast.Expr) {
call := astcast.ToCallExpr(expr)
if qualifiedName(call.Fun) != "filepath.Join" {
return
}

for _, arg := range call.Args {
arg, ok := arg.(*ast.BasicLit)
if ok && c.hasSeparator(arg) {
c.warnSeparator(arg)
}
}
}

func (c *filepathJoinChecker) hasSeparator(v *ast.BasicLit) bool {
return strings.ContainsAny(v.Value, `/\`)
}

func (c *filepathJoinChecker) warnSeparator(sep ast.Expr) {
c.ctx.Warn(sep, "%s contains a path separator", sep)
}
16 changes: 16 additions & 0 deletions checkers/testdata/filepathJoin/negative_tests.go
@@ -0,0 +1,16 @@
package checker_test

import (
"path/filepath"
)

func badArgs() {
filename := "file.go"
dir := "testdata"

_ = filepath.Join("testdata", filename)

_ = filepath.Join(dir, "file.go")

_ = filepath.Join(`testdata`, `a`, `b.txt`)
}
20 changes: 20 additions & 0 deletions checkers/testdata/filepathJoin/positive_tests.go
@@ -0,0 +1,20 @@
package checker_test

import (
"path/filepath"
)

func badArgs() {
filename := "file.go"
dir := "testdata"

/*! "testdata/" contains a path separator */
_ = filepath.Join("testdata/", filename)

/*! "/file.go" contains a path separator */
_ = filepath.Join(dir, "/file.go")

/*! `\a\b.txt` contains a path separator */
/*! `testdata\` contains a path separator */
_ = filepath.Join(`testdata\`, `\a\b.txt`)
}

0 comments on commit 9ac4766

Please sign in to comment.