Derive the package from given files

Move some utility functions into the helper
This commit is contained in:
Cosmin Cojocar 2018-07-23 15:16:47 +02:00
parent 3f2b81461f
commit 4c6396b7d4
3 changed files with 71 additions and 45 deletions

View file

@ -28,8 +28,6 @@ import (
"regexp" "regexp"
"strings" "strings"
"path/filepath"
"golang.org/x/tools/go/loader" "golang.org/x/tools/go/loader"
) )
@ -106,11 +104,8 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
AllowErrors: true, AllowErrors: true,
} }
for _, packagePath := range packagePaths { for _, packagePath := range packagePaths {
abspath, err := filepath.Abs(packagePath) abspath, err := GetPkgAbsPath(packagePath)
if err != nil { if err != nil {
return err
}
if _, err := os.Stat(abspath); os.IsNotExist(err) {
gosec.logger.Printf("Skipping: %s. Path doesn't exist.", abspath) gosec.logger.Printf("Skipping: %s. Path doesn't exist.", abspath)
continue continue
} }

View file

@ -20,10 +20,8 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"os/user"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime"
"sort" "sort"
"strings" "strings"
@ -178,36 +176,13 @@ func saveOutput(filename, format string, issues []*gosec.Issue, metrics *gosec.M
return nil return nil
} }
func getenv(key, userDefault string) string { func cleanPath(path string) (string, error) {
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) {
cleanFailed := fmt.Errorf("%s is not within the $GOPATH and cannot be processed", path) cleanFailed := fmt.Errorf("%s is not within the $GOPATH and cannot be processed", path)
nonRecursivePath := strings.TrimSuffix(path, "/...") nonRecursivePath := strings.TrimSuffix(path, "/...")
// do not attempt to clean directs that are resolvable on gopath // do not attempt to clean directs that are resolvable on gopath
if _, err := os.Stat(nonRecursivePath); err != nil && os.IsNotExist(err) { 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) 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) dir := filepath.Join(basedir, "src", nonRecursivePath)
if st, err := os.Stat(dir); err == nil && st.IsDir() { if st, err := os.Stat(dir); err == nil && st.IsDir() {
log.Printf("located %s in %s", path, dir) 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 // ensure we resolve package directory correctly based on $GOPATH
abspath, err := filepath.Abs(path) pkgPath, err := gosec.GetPkgRelativePath(path)
if err != nil { if err != nil {
abspath = path return "", cleanFailed
} }
for _, base := range gopaths { return pkgPath, nil
projectRoot := filepath.FromSlash(fmt.Sprintf("%s/src/", base))
if strings.HasPrefix(abspath, projectRoot) {
return strings.TrimPrefix(abspath, projectRoot), nil
}
}
return "", cleanFailed
} }
func cleanPaths(paths []string) []string { func cleanPaths(paths []string) []string {
gopaths := gopath()
var clean []string var clean []string
for _, path := range paths { for _, path := range paths {
cleaned, err := cleanPath(path, gopaths) cleaned, err := cleanPath(path)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -306,7 +274,7 @@ func main() {
var packages []string var packages []string
// Iterate over packages on the import paths // Iterate over packages on the import paths
gopaths := gopath() gopaths := gosec.Gopath()
for _, pkg := range gotool.ImportPaths(cleanPaths(flag.Args())) { for _, pkg := range gotool.ImportPaths(cleanPaths(flag.Args())) {
// Skip vendor directory // Skip vendor directory

View file

@ -15,11 +15,17 @@
package gosec package gosec
import ( import (
"errors"
"fmt" "fmt"
"go/ast" "go/ast"
"go/token" "go/token"
"go/types" "go/types"
"os"
"os/user"
"path/filepath"
"runtime"
"strconv" "strconv"
"strings"
) )
// MatchCallByPackage ensures that the specified package is imported, // 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()) fobj := ctx.FileSet.File(n.Pos())
return fobj.Name(), fobj.Line(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
}