diff options
author | Bryan C. Mills <bcmills@google.com> | 2020-02-28 15:03:54 -0500 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2020-02-28 21:56:35 +0000 |
commit | 618126b9895db7f29a861caa4e330d149858ff56 (patch) | |
tree | 14b22fa6de658827549b6c2e8d6f17bf2d102207 /src/cmd/go/internal/search/search.go | |
parent | 964fac3ee74fe4df5423dad18f78322d88aae84a (diff) | |
download | go-618126b9895db7f29a861caa4e330d149858ff56.tar.gz go-618126b9895db7f29a861caa4e330d149858ff56.zip |
cmd/go: avoid matching wildcards rooted outside of available modules
To avoid confusion, also distinguish between packages and dirs in
search.Match results.
No test because this is technically only a performance optimization:
it would be very difficult to write such a test so that it would not
be flaky. (However, tested the change manually.)
Fixes #37521
Change-Id: I17b443699ce6a8f3a63805a7ef0be806f695a4b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/221544
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src/cmd/go/internal/search/search.go')
-rw-r--r-- | src/cmd/go/internal/search/search.go | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/src/cmd/go/internal/search/search.go b/src/cmd/go/internal/search/search.go index 69d0e2d16f..b588c3e467 100644 --- a/src/cmd/go/internal/search/search.go +++ b/src/cmd/go/internal/search/search.go @@ -19,7 +19,8 @@ import ( // A Match represents the result of matching a single package pattern. type Match struct { pattern string // the pattern itself - Pkgs []string // matching packages (dirs or import paths) + Dirs []string // if the pattern is local, directories that potentially contain matching packages + Pkgs []string // matching packages (import paths) Errs []error // errors matching the patterns to packages, NOT errors loading those packages // Errs may be non-empty even if len(Pkgs) > 0, indicating that some matching @@ -84,20 +85,25 @@ func (e *MatchError) Unwrap() error { return e.Err } -// MatchPackages sets m.Pkgs to contain all the packages that can be found -// under the $GOPATH directories and $GOROOT matching pattern. -// The pattern is either "all" (all packages), "std" (standard packages), -// "cmd" (standard commands), or a path including "...". +// MatchPackages sets m.Pkgs to a non-nil slice containing all the packages that +// can be found under the $GOPATH directories and $GOROOT that match the +// pattern. The pattern must be either "all" (all packages), "std" (standard +// packages), "cmd" (standard commands), or a path including "...". // -// MatchPackages sets m.Errs to contain any errors encountered while processing -// the match. +// If any errors may have caused the set of packages to be incomplete, +// MatchPackages appends those errors to m.Errs. func (m *Match) MatchPackages() { - m.Pkgs, m.Errs = nil, nil + m.Pkgs = []string{} if m.IsLocal() { m.AddError(fmt.Errorf("internal error: MatchPackages: %s is not a valid package pattern", m.pattern)) return } + if m.IsLiteral() { + m.Pkgs = []string{m.pattern} + return + } + match := func(string) bool { return true } treeCanMatch := func(string) bool { return true } if !m.IsMeta() { @@ -197,16 +203,22 @@ func SetModRoot(dir string) { modRoot = dir } -// MatchPackagesInFS is like MatchPackages but is passed a pattern that -// begins with an absolute path or "./" or "../". On Windows, the pattern may -// use slash or backslash separators or a mix of both. +// MatchDirs sets m.Dirs to a non-nil slice containing all directories that +// potentially match a local pattern. The pattern must begin with an absolute +// path, or "./", or "../". On Windows, the pattern may use slash or backslash +// separators or a mix of both. // -// MatchPackagesInFS scans the tree rooted at the directory that contains the -// first "..." wildcard. -func (m *Match) MatchPackagesInFS() { - m.Pkgs, m.Errs = nil, nil +// If any errors may have caused the set of directories to be incomplete, +// MatchDirs appends those errors to m.Errs. +func (m *Match) MatchDirs() { + m.Dirs = []string{} if !m.IsLocal() { - m.AddError(fmt.Errorf("internal error: MatchPackagesInFS: %s is not a valid filesystem pattern", m.pattern)) + m.AddError(fmt.Errorf("internal error: MatchDirs: %s is not a valid filesystem pattern", m.pattern)) + return + } + + if m.IsLiteral() { + m.Dirs = []string{m.pattern} return } @@ -301,7 +313,7 @@ func (m *Match) MatchPackagesInFS() { // which is all that Match promises to do. // Ignore the import error. } - m.Pkgs = append(m.Pkgs, name) + m.Dirs = append(m.Dirs, name) return nil }) if err != nil { @@ -416,25 +428,23 @@ func ImportPathsQuiet(patterns []string) []*Match { for _, a := range CleanPatterns(patterns) { m := NewMatch(a) if m.IsLocal() { - if m.IsLiteral() { - m.Pkgs = []string{a} - } else { - m.MatchPackagesInFS() - } + m.MatchDirs() // Change the file import path to a regular import path if the package // is in GOPATH or GOROOT. We don't report errors here; LoadImport // (or something similar) will report them later. - for i, dir := range m.Pkgs { + m.Pkgs = make([]string, len(m.Dirs)) + for i, dir := range m.Dirs { + absDir := dir if !filepath.IsAbs(dir) { - dir = filepath.Join(base.Cwd, dir) + absDir = filepath.Join(base.Cwd, dir) } - if bp, _ := cfg.BuildContext.ImportDir(dir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." { + if bp, _ := cfg.BuildContext.ImportDir(absDir, build.FindOnly); bp.ImportPath != "" && bp.ImportPath != "." { m.Pkgs[i] = bp.ImportPath + } else { + m.Pkgs[i] = dir } } - } else if m.IsLiteral() { - m.Pkgs = []string{a} } else { m.MatchPackages() } |