cmd/go/internal/modfetch: fix bug in parsing non-quoted module paths
CL 105215 introduced "allow, prefer unquoted strings in mod files",
so autogenerated go.mod files do not contain quotes in the module path.
Before, `modPath` could only handle quoted module paths. This lead to
bugs like `vgo install github.com/Kyroy/vgoversion2/v2` installing
v1.0.0 instead of v2.1.0 because `isMajor` returned false instead of
true due to the wrong return of modPath. Hence, `findDir` returned
"missing go.mod" error.
Now, `modPath` is able to parse quoted and non-quoted module paths.
Change-Id: I24b0a4cd60ce928b123fb1b347edf84f018f01a6
Reviewed-on: https://go-review.googlesource.com/114058
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/vendor/cmd/go/internal/modfetch/coderepo.go b/vendor/cmd/go/internal/modfetch/coderepo.go
index ffbd223..bb6e8ac 100644
--- a/vendor/cmd/go/internal/modfetch/coderepo.go
+++ b/vendor/cmd/go/internal/modfetch/coderepo.go
@@ -234,7 +234,7 @@
if found1 {
return rev, r.codeDir, gomod1, nil
}
- return "", "", nil, fmt.Errorf("missing go.mod")
+ return "", "", nil, fmt.Errorf("missing or invalid go.mod")
}
func isMajor(gomod []byte, pathMajor string) bool {
@@ -257,25 +257,19 @@
line = line[len(moduleStr):]
n := len(line)
line = bytes.TrimSpace(line)
- if len(line) == n || len(line) == 0 || line[0] != '"' && line[0] != '`' {
+ if len(line) == n || len(line) == 0 {
continue
}
- q := line[0]
- i := 1
- for i < len(line) && line[i] != q {
- if q == '"' && line[i] == '\\' {
- i++
+
+ if line[0] == '"' || line[0] == '`' {
+ p, err := strconv.Unquote(string(line))
+ if err != nil {
+ return "" // malformed quoted string or multiline module path
}
- i++
+ return p
}
- if i >= len(line) {
- return "" // malformed quoted string or multiline module path
- }
- p, err := strconv.Unquote(string(line[:i+1]))
- if err != nil {
- return ""
- }
- return p
+
+ return string(line)
}
return "" // missing module path
}
diff --git a/vendor/cmd/go/internal/modfetch/coderepo_test.go b/vendor/cmd/go/internal/modfetch/coderepo_test.go
index 8821b02..80415b4 100644
--- a/vendor/cmd/go/internal/modfetch/coderepo_test.go
+++ b/vendor/cmd/go/internal/modfetch/coderepo_test.go
@@ -657,3 +657,39 @@
t.Fatal("unexpected versions returned:", v)
}
}
+
+var modPathTests = []struct {
+ input []byte
+ expected string
+}{
+ {input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
+ {input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
+ {input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"},
+ {input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"},
+ {input: []byte("module `github.com/rsc/vgotest`"), expected: "github.com/rsc/vgotest"},
+ {input: []byte("module \"github.com/rsc/vgotest/v2\""), expected: "github.com/rsc/vgotest/v2"},
+ {input: []byte("module github.com/rsc/vgotest/v2"), expected: "github.com/rsc/vgotest/v2"},
+ {input: []byte("module \"gopkg.in/yaml.v2\""), expected: "gopkg.in/yaml.v2"},
+ {input: []byte("module gopkg.in/yaml.v2"), expected: "gopkg.in/yaml.v2"},
+ {input: []byte("module \"gopkg.in/check.v1\"\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module \"gopkg.in/check.v1\n\""), expected: ""},
+ {input: []byte("module gopkg.in/check.v1\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module \"gopkg.in/check.v1\"\r\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module gopkg.in/check.v1\r\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module \"gopkg.in/check.v1\"\n\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module gopkg.in/check.v1\n\n"), expected: "gopkg.in/check.v1"},
+ {input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""},
+ {input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""},
+ {input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""},
+}
+
+func TestModPath(t *testing.T) {
+ for _, test := range modPathTests {
+ t.Run(string(test.input), func(t *testing.T) {
+ result := modPath(test.input)
+ if result != test.expected {
+ t.Fatalf("modPath(%s): %s, want %s", string(test.input), result, test.expected)
+ }
+ })
+ }
+}