cmd/go/internal/search: add SetModRoot to limit fs patterns
diff --git a/vendor/cmd/go/internal/search/search.go b/vendor/cmd/go/internal/search/search.go index ab31ab6..8b2f7c6 100644 --- a/vendor/cmd/go/internal/search/search.go +++ b/vendor/cmd/go/internal/search/search.go
@@ -5,6 +5,7 @@ package search import ( + "cmd/go/internal/base" "cmd/go/internal/cfg" "fmt" "go/build" @@ -129,6 +130,12 @@ return pkgs } +var modRoot string + +func SetModRoot(dir string) { + modRoot = dir +} + // MatchPackagesInFS returns a list of package paths matching pattern, // which must begin with ./ or ../ // (see go help packages for pattern syntax). @@ -150,6 +157,17 @@ } match := MatchPattern(pattern) + if modRoot != "" { + abs, err := filepath.Abs(dir) + if err != nil { + base.Fatalf("go: %v", err) + } + if !hasFilepathPrefix(abs, modRoot) { + base.Fatalf("go: pattern %s refers to dir %s, outside module root %s", pattern, abs, modRoot) + return nil + } + } + var pkgs []string filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { if err != nil || !fi.IsDir() { @@ -369,6 +387,22 @@ } } +// hasFilepathPrefix reports whether the path s begins with the +// elements in prefix. +func hasFilepathPrefix(s, prefix string) bool { + switch { + default: + return false + case len(s) == len(prefix): + return s == prefix + case len(s) > len(prefix): + if prefix != "" && prefix[len(prefix)-1] == filepath.Separator { + return strings.HasPrefix(s, prefix) + } + return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix + } +} + // IsStandardImportPath reports whether $GOROOT/src/path should be considered // part of the standard distribution. For historical reasons we allow people to add // their own code to $GOROOT instead of using $GOPATH, but we assume that