From b806054097c2941f0f5fe25f7eb264e5cf04608b Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Sat, 22 Jul 2017 17:39:13 -0700 Subject: [PATCH] resolver.ResolveLocal: fully dereference basedir before walking Commit 52f7192 taught NewResolver to detect when the basedir argument is a symlink and to extract the target of the symlink and use it in place of the original basedir. This works correctly and allows ResolveLocal to walk the directory tree when the symlink target is a fully qualified path to a directory. But, if the symlink points to another symlink, or if it provides a relative path, then the traversal by filepath.Walk() will fail as before. The path/filepath package already provides a function to fully evaluate a path and dereference any symbolic links: filepath.EvalSymlinks(). So instead of using checkForBasedirSymlink() to perform a single dereference of basedir and storing that into the Resolver object, let's just record the original path into the Resolver object and then call filepath.EvalSymlinks() to fully resolve the path in ResolveLocal before walking the tree with filepath.Walk(). --- dependency/resolver.go | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/dependency/resolver.go b/dependency/resolver.go index bf59c3e3..9ce89ef6 100644 --- a/dependency/resolver.go +++ b/dependency/resolver.go @@ -185,12 +185,6 @@ func NewResolver(basedir string) (*Resolver, error) { return nil, err } - basedir, err = checkForBasedirSymlink(basedir) - - if err != nil { - return nil, err - } - vdir := filepath.Join(basedir, "vendor") buildContext, err := util.GetBuildContext() @@ -266,11 +260,17 @@ func (r *Resolver) ResolveLocal(deep bool) ([]string, []string, error) { tl := list.New() alreadySeen := map[string]bool{} talreadySeen := map[string]bool{} - err := filepath.Walk(r.basedir, func(path string, fi os.FileInfo, err error) error { + + basedir, err := filepath.EvalSymlinks(r.basedir) + if err != nil { + return nil, nil, err + } + + err = filepath.Walk(basedir, func(path string, fi os.FileInfo, err error) error { if err != nil && err != filepath.SkipDir { return err } - pt := strings.TrimPrefix(path, r.basedir+string(os.PathSeparator)) + pt := strings.TrimPrefix(path, basedir+string(os.PathSeparator)) pt = strings.TrimSuffix(pt, string(os.PathSeparator)) if r.Config.HasExclude(pt) { msg.Debug("Excluding %s", pt) @@ -1100,23 +1100,6 @@ func srcDir(fi os.FileInfo) bool { return true } -// checkForBasedirSymlink checks to see if the given basedir is actually a -// symlink. In the case that it is a symlink, the symlink is read and returned. -// If the basedir is not a symlink, the provided basedir argument is simply -// returned back to the caller. -func checkForBasedirSymlink(basedir string) (string, error) { - fi, err := os.Lstat(basedir) - if err != nil { - return "", err - } - - if fi.Mode()&os.ModeSymlink != 0 { - return os.Readlink(basedir) - } - - return basedir, nil -} - // helper func to merge, dedupe, and sort strings func dedupeStrings(s1, s2 []string) (r []string) { dedupe := make(map[string]bool)