aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2018-08-19 13:53:57 +0100
committerBrad Fitzpatrick <bradfitz@golang.org>2018-08-21 02:25:39 +0000
commitece4cdb9cb5d49efb1a7a43cc7d0501b0f3a9f60 (patch)
treef4c88b12fd062504fa9fe581c6ad18dbd34673a3
parent673a05e4dfcbaa3a64f5a5eb38444aff593714e0 (diff)
downloadgo-ece4cdb9cb5d49efb1a7a43cc7d0501b0f3a9f60.tar.gz
go-ece4cdb9cb5d49efb1a7a43cc7d0501b0f3a9f60.zip
[release-branch.go1.11] cmd/go: fix modload infinite directory loop
It is possible to enter the parent-walking directory loop in a way that it will loop forever - if mdir is empty, and d reaches ".". To avoid this, make sure that the 'd = filepath.Dir(d)' step only happens if the parent directory is actually different than the current directory. This fixes some of the tests like TestImport/golang.org_x_net_context, which were never finishing before. While at it, also fix TestImport/golang.org_x_net, which seems to have the wrong expected error. The root of the x/net repo doesn't have a go.mod file, nor is part of a module itself, so it seems like the expected error should reflect that. After these two changes, 'go test cmd/go/internal/modload' passes on my linux/amd64 machine. Fixes #27080. Change-Id: Ie8bab0f9fbc9f447844cbbc64117420d9087db1b Reviewed-on: https://go-review.googlesource.com/129778 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> (cherry picked from commit 692307aa839252285ebb91b4072e3c05ff554341) Reviewed-on: https://go-review.googlesource.com/130275 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Andrew Bonventre <andybons@golang.org>
-rw-r--r--src/cmd/go/internal/modload/import.go9
-rw-r--r--src/cmd/go/internal/modload/import_test.go2
2 files changed, 9 insertions, 2 deletions
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index 78ae83e4bf..12d9407f6e 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -181,7 +181,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile
// So we only check local module trees
// (the main module, and any directory trees pointed at by replace directives).
if isLocal {
- for d := dir; d != mdir && len(d) > len(mdir); d = filepath.Dir(d) {
+ for d := dir; d != mdir && len(d) > len(mdir); {
haveGoMod := haveGoModCache.Do(d, func() interface{} {
_, err := os.Stat(filepath.Join(d, "go.mod"))
return err == nil
@@ -190,6 +190,13 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile
if haveGoMod {
return "", false
}
+ parent := filepath.Dir(d)
+ if parent == d {
+ // Break the loop, as otherwise we'd loop
+ // forever if d=="." and mdir=="".
+ break
+ }
+ d = parent
}
}
diff --git a/src/cmd/go/internal/modload/import_test.go b/src/cmd/go/internal/modload/import_test.go
index 8e01dc5091..3f4ddab436 100644
--- a/src/cmd/go/internal/modload/import_test.go
+++ b/src/cmd/go/internal/modload/import_test.go
@@ -21,7 +21,7 @@ var importTests = []struct {
},
{
path: "golang.org/x/net",
- err: "missing module for import: golang.org/x/net@.* provides golang.org/x/net",
+ err: "cannot find module providing package golang.org/x/net",
},
{
path: "golang.org/x/text",