]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.11] cmd/go: fix modload infinite directory loop
authorDaniel Martí <mvdan@mvdan.cc>
Sun, 19 Aug 2018 12:53:57 +0000 (13:53 +0100)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 21 Aug 2018 02:25:39 +0000 (02:25 +0000)
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>
src/cmd/go/internal/modload/import.go
src/cmd/go/internal/modload/import_test.go

index 78ae83e4bf3b5b1e2a79f2c76cda8f938e80d2db..12d9407f6e6966bcf40d9d9896abfcd0894f3a98 100644 (file)
@@ -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
                }
        }
 
index 8e01dc50916a39d27198515085e9293b2fe45f61..3f4ddab436cc49a79dc74c852d2b3acd66e4fc79 100644 (file)
@@ -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",