128 lines
4.4 KiB
Diff
128 lines
4.4 KiB
Diff
diff -up go/src/cmd/go/get.go.cve go/src/cmd/go/get.go
|
|
--- go/src/cmd/go/get.go.cve 2017-05-23 20:35:22.000000000 +0200
|
|
+++ go/src/cmd/go/get.go 2017-10-10 10:25:24.485047705 +0200
|
|
@@ -401,6 +401,11 @@ func downloadPackage(p *Package) error {
|
|
p.build.PkgRoot = filepath.Join(list[0], "pkg")
|
|
}
|
|
root := filepath.Join(p.build.SrcRoot, filepath.FromSlash(rootPath))
|
|
+
|
|
+ if err := checkNestedVCS(vcs, root, p.build.SrcRoot); err != nil {
|
|
+ return err
|
|
+ }
|
|
+
|
|
// If we've considered this repository already, don't do it again.
|
|
if downloadRootCache[root] {
|
|
return nil
|
|
diff -up go/src/cmd/go/go_test.go.cve go/src/cmd/go/go_test.go
|
|
--- go/src/cmd/go/go_test.go.cve 2017-05-23 20:35:22.000000000 +0200
|
|
+++ go/src/cmd/go/go_test.go 2017-10-10 10:25:24.485047705 +0200
|
|
@@ -1235,6 +1235,25 @@ func TestGetGitDefaultBranch(t *testing.
|
|
tg.grepStdout(`\* another-branch`, "not on correct default branch")
|
|
}
|
|
|
|
+func TestAccidentalGitCheckout(t *testing.T) {
|
|
+ testenv.MustHaveExternalNetwork(t)
|
|
+ if _, err := exec.LookPath("git"); err != nil {
|
|
+ t.Skip("skipping because git binary not found")
|
|
+ }
|
|
+
|
|
+ tg := testgo(t)
|
|
+ defer tg.cleanup()
|
|
+ tg.parallel()
|
|
+ tg.tempDir("src")
|
|
+ tg.setenv("GOPATH", tg.path("."))
|
|
+
|
|
+ tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
|
|
+ tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
|
|
+
|
|
+ tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
|
|
+ tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
|
|
+}
|
|
+
|
|
func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
|
|
tg := testgo(t)
|
|
defer tg.cleanup()
|
|
diff -up go/src/cmd/go/vcs.go.cve go/src/cmd/go/vcs.go
|
|
--- go/src/cmd/go/vcs.go.cve 2017-05-23 20:35:22.000000000 +0200
|
|
+++ go/src/cmd/go/vcs.go 2017-10-10 10:30:52.151621206 +0200
|
|
@@ -479,11 +479,29 @@ func vcsFromDir(dir, srcRoot string) (vc
|
|
return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
|
|
}
|
|
|
|
+ var vcsRet *vcsCmd
|
|
+ var rootRet string
|
|
+
|
|
origDir := dir
|
|
for len(dir) > len(srcRoot) {
|
|
for _, vcs := range vcsList {
|
|
if fi, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil && fi.IsDir() {
|
|
- return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil
|
|
+ root := filepath.ToSlash(dir[len(srcRoot)+1:])
|
|
+ // Record first VCS we find, but keep looking,
|
|
+ // to detect mistakes like one kind of VCS inside another.
|
|
+ if vcsRet == nil {
|
|
+ vcsRet = vcs
|
|
+ rootRet = root
|
|
+ continue
|
|
+ }
|
|
+ // Allow .git inside .git, which can arise due to submodules.
|
|
+ if vcsRet == vcs && vcs.cmd == "git" {
|
|
+ continue
|
|
+ }
|
|
+ // Otherwise, we have one VCS inside a different VCS.
|
|
+ return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s",
|
|
+ filepath.Join(srcRoot, rootRet), vcsRet.cmd, filepath.Join(srcRoot, root), vcs.cmd)
|
|
+
|
|
}
|
|
}
|
|
|
|
@@ -496,9 +514,48 @@ func vcsFromDir(dir, srcRoot string) (vc
|
|
dir = ndir
|
|
}
|
|
|
|
+ if vcsRet != nil {
|
|
+ return vcsRet, rootRet, nil
|
|
+ }
|
|
+
|
|
return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
|
|
}
|
|
|
|
+// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS
|
|
+// situation for dir, checking parents up until srcRoot.
|
|
+func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error {
|
|
+ if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
|
|
+ return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
|
|
+ }
|
|
+
|
|
+ otherDir := dir
|
|
+ for len(otherDir) > len(srcRoot) {
|
|
+ for _, otherVCS := range vcsList {
|
|
+ if _, err := os.Stat(filepath.Join(dir, "."+otherVCS.cmd)); err == nil {
|
|
+ // Allow expected vcs in original dir.
|
|
+ if otherDir == dir && otherVCS == vcs {
|
|
+ continue
|
|
+ }
|
|
+ // Allow .git inside .git, which can arise due to submodules.
|
|
+ if otherVCS == vcs && vcs.cmd == "git" {
|
|
+ continue
|
|
+ }
|
|
+ // Otherwise, we have one VCS inside a different VCS.
|
|
+ return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.cmd, otherDir, otherVCS.cmd)
|
|
+ }
|
|
+ }
|
|
+ // Move to parent.
|
|
+ newDir := filepath.Dir(otherDir)
|
|
+ if len(newDir) >= len(otherDir) {
|
|
+ // Shouldn't happen, but just in case, stop.
|
|
+ break
|
|
+ }
|
|
+ otherDir = newDir
|
|
+ }
|
|
+
|
|
+ return nil
|
|
+}
|
|
+
|
|
// repoRoot represents a version control system, a repo, and a root of
|
|
// where to put it on disk.
|
|
type repoRoot struct {
|