From 692307aa839252285ebb91b4072e3c05ff554341 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Mart=C3=AD?= Date: Sun, 19 Aug 2018 13:53:57 +0100 Subject: [PATCH] cmd/go: fix modload infinite directory loop MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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í TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/go/internal/modload/import.go | 9 ++++++++- src/cmd/go/internal/modload/import_test.go | 2 +- 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", -- 2.48.1