From 4c6396b7d4e2cea5e9332d5802f7a31b6bb29133 Mon Sep 17 00:00:00 2001 From: Cosmin Cojocar Date: Mon, 23 Jul 2018 15:16:47 +0200 Subject: [PATCH] Derive the package from given files Move some utility functions into the helper --- analyzer.go | 7 +----- cmd/gosec/main.go | 46 ++++++---------------------------- helpers.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 45 deletions(-) diff --git a/analyzer.go b/analyzer.go index e21722f..231b718 100644 --- a/analyzer.go +++ b/analyzer.go @@ -28,8 +28,6 @@ import ( "regexp" "strings" - "path/filepath" - "golang.org/x/tools/go/loader" ) @@ -106,11 +104,8 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error AllowErrors: true, } for _, packagePath := range packagePaths { - abspath, err := filepath.Abs(packagePath) + abspath, err := GetPkgAbsPath(packagePath) if err != nil { - return err - } - if _, err := os.Stat(abspath); os.IsNotExist(err) { gosec.logger.Printf("Skipping: %s. Path doesn't exist.", abspath) continue } diff --git a/cmd/gosec/main.go b/cmd/gosec/main.go index df88a19..3d6479a 100644 --- a/cmd/gosec/main.go +++ b/cmd/gosec/main.go @@ -20,10 +20,8 @@ import ( "io/ioutil" "log" "os" - "os/user" "path/filepath" "regexp" - "runtime" "sort" "strings" @@ -178,36 +176,13 @@ func saveOutput(filename, format string, issues []*gosec.Issue, metrics *gosec.M return nil } -func getenv(key, userDefault string) string { - if val := os.Getenv(key); val != "" { - return val - } - return userDefault -} - -func gopath() []string { - defaultGoPath := runtime.GOROOT() - if u, err := user.Current(); err == nil { - defaultGoPath = filepath.Join(u.HomeDir, "go") - } - path := getenv("GOPATH", defaultGoPath) - paths := strings.Split(path, string(os.PathListSeparator)) - for idx, path := range paths { - if abs, err := filepath.Abs(path); err == nil { - paths[idx] = abs - } - } - return paths -} - -func cleanPath(path string, gopaths []string) (string, error) { - +func cleanPath(path string) (string, error) { cleanFailed := fmt.Errorf("%s is not within the $GOPATH and cannot be processed", path) nonRecursivePath := strings.TrimSuffix(path, "/...") // do not attempt to clean directs that are resolvable on gopath if _, err := os.Stat(nonRecursivePath); err != nil && os.IsNotExist(err) { log.Printf("directory %s doesn't exist, checking if is a package on $GOPATH", path) - for _, basedir := range gopaths { + for _, basedir := range gosec.Gopath() { dir := filepath.Join(basedir, "src", nonRecursivePath) if st, err := os.Stat(dir); err == nil && st.IsDir() { log.Printf("located %s in %s", path, dir) @@ -218,24 +193,17 @@ func cleanPath(path string, gopaths []string) (string, error) { } // ensure we resolve package directory correctly based on $GOPATH - abspath, err := filepath.Abs(path) + pkgPath, err := gosec.GetPkgRelativePath(path) if err != nil { - abspath = path + return "", cleanFailed } - for _, base := range gopaths { - projectRoot := filepath.FromSlash(fmt.Sprintf("%s/src/", base)) - if strings.HasPrefix(abspath, projectRoot) { - return strings.TrimPrefix(abspath, projectRoot), nil - } - } - return "", cleanFailed + return pkgPath, nil } func cleanPaths(paths []string) []string { - gopaths := gopath() var clean []string for _, path := range paths { - cleaned, err := cleanPath(path, gopaths) + cleaned, err := cleanPath(path) if err != nil { log.Fatal(err) } @@ -306,7 +274,7 @@ func main() { var packages []string // Iterate over packages on the import paths - gopaths := gopath() + gopaths := gosec.Gopath() for _, pkg := range gotool.ImportPaths(cleanPaths(flag.Args())) { // Skip vendor directory diff --git a/helpers.go b/helpers.go index 515ee8b..abe4c15 100644 --- a/helpers.go +++ b/helpers.go @@ -15,11 +15,17 @@ package gosec import ( + "errors" "fmt" "go/ast" "go/token" "go/types" + "os" + "os/user" + "path/filepath" + "runtime" "strconv" + "strings" ) // MatchCallByPackage ensures that the specified package is imported, @@ -193,3 +199,60 @@ func GetLocation(n ast.Node, ctx *Context) (string, int) { fobj := ctx.FileSet.File(n.Pos()) return fobj.Name(), fobj.Line(n.Pos()) } + +// Gopath returns all GOPATHs +func Gopath() []string { + defaultGoPath := runtime.GOROOT() + if u, err := user.Current(); err == nil { + defaultGoPath = filepath.Join(u.HomeDir, "go") + } + path := Getenv("GOPATH", defaultGoPath) + paths := strings.Split(path, string(os.PathListSeparator)) + for idx, path := range paths { + if abs, err := filepath.Abs(path); err == nil { + paths[idx] = abs + } + } + return paths +} + +// Getenv returns the values of the environment variable, otherwise +//returns the default if variable is not set +func Getenv(key, userDefault string) string { + if val := os.Getenv(key); val != "" { + return val + } + return userDefault +} + +// GetPkgRelativePath returns the Go relative relative path derived +// form the given path +func GetPkgRelativePath(path string) (string, error) { + abspath, err := filepath.Abs(path) + if err != nil { + abspath = path + } + if strings.HasSuffix(abspath, ".go") { + abspath = filepath.Dir(abspath) + } + for _, base := range Gopath() { + projectRoot := filepath.FromSlash(fmt.Sprintf("%s/src/", base)) + if strings.HasPrefix(abspath, projectRoot) { + return strings.TrimPrefix(abspath, projectRoot), nil + } + } + return "", errors.New("no project relative path found") +} + +// GetPkgAbsPath returns the Go package absolute path derived from +// the given path +func GetPkgAbsPath(pkgPath string) (string, error) { + absPath, err := filepath.Abs(pkgPath) + if err != nil { + return "", err + } + if _, err := os.Stat(absPath); os.IsNotExist(err) { + return "", errors.New("no project absolute path found") + } + return absPath, nil +}