mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd: upgrade golang.org/x/mod to relax import path check
This incorporates CL 297089, which allows leading dots in import path elements but not module path elements. Also added a test. Fixes #43985 Updates #34992 Change-Id: I2d5faabd8f7b23a7943d3f3ccb6707ab5dc2ce3c Reviewed-on: https://go-review.googlesource.com/c/go/+/297530 Trust: Jay Conrod <jayconrod@google.com> Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
f6a74c6568
commit
97bdac03ae
6 changed files with 82 additions and 20 deletions
|
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
|
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
|
||||||
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
|
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||||
golang.org/x/mod v0.4.2-0.20210225160341-66bf157bf5bc
|
golang.org/x/mod v0.4.2-0.20210301144719-c8bb1bd8a2aa
|
||||||
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e // indirect
|
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e // indirect
|
||||||
golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f
|
golang.org/x/tools v0.1.1-0.20210220032852-2363391a5b2f
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2-0.20210225160341-66bf157bf5bc h1:xQukuh0OD2SNSUK1CCBFATgHYx5ye75S/bAWEU/PT0E=
|
golang.org/x/mod v0.4.2-0.20210301144719-c8bb1bd8a2aa h1:Ci2bbuyE4ah9djFByg+fdNQcqc8DVSdcXbrWy6MBoEs=
|
||||||
golang.org/x/mod v0.4.2-0.20210225160341-66bf157bf5bc/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2-0.20210301144719-c8bb1bd8a2aa/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ func downloadPackage(p *load.Package) error {
|
||||||
}
|
}
|
||||||
importPrefix = importPrefix[:slash]
|
importPrefix = importPrefix[:slash]
|
||||||
}
|
}
|
||||||
if err := module.CheckImportPath(importPrefix); err != nil {
|
if err := checkImportPath(importPrefix); err != nil {
|
||||||
return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
|
return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err)
|
||||||
}
|
}
|
||||||
security := web.SecureOnly
|
security := web.SecureOnly
|
||||||
|
|
@ -591,3 +591,31 @@ func selectTag(goVersion string, tags []string) (match string) {
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkImportPath is like module.CheckImportPath, but it forbids leading dots
|
||||||
|
// in path elements. This can lead to 'go get' creating .git and other VCS
|
||||||
|
// directories in places we might run VCS tools later.
|
||||||
|
func checkImportPath(path string) error {
|
||||||
|
if err := module.CheckImportPath(path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
checkElem := func(elem string) error {
|
||||||
|
if elem[0] == '.' {
|
||||||
|
return fmt.Errorf("malformed import path %q: leading dot in path element", path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
elemStart := 0
|
||||||
|
for i, r := range path {
|
||||||
|
if r == '/' {
|
||||||
|
if err := checkElem(path[elemStart:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
elemStart = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := checkElem(path[elemStart:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
24
src/cmd/go/testdata/script/mod_invalid_path.txt
vendored
24
src/cmd/go/testdata/script/mod_invalid_path.txt
vendored
|
|
@ -23,6 +23,20 @@ cd $WORK/gopath/src/badname
|
||||||
! go list .
|
! go list .
|
||||||
stderr 'invalid module path'
|
stderr 'invalid module path'
|
||||||
|
|
||||||
|
# Test that an import path containing an element with a leading dot is valid,
|
||||||
|
# but such a module path is not.
|
||||||
|
# Verifies #43985.
|
||||||
|
cd $WORK/gopath/src/dotname
|
||||||
|
go list ./.dot
|
||||||
|
stdout '^example.com/dotname/.dot$'
|
||||||
|
go list ./use
|
||||||
|
stdout '^example.com/dotname/use$'
|
||||||
|
! go list -m example.com/dotname/.dot@latest
|
||||||
|
stderr '^go list -m: example.com/dotname/.dot@latest: malformed module path "example.com/dotname/.dot": leading dot in path element$'
|
||||||
|
go get -d example.com/dotname/.dot
|
||||||
|
go get -d example.com/dotname/use
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
-- mod/go.mod --
|
-- mod/go.mod --
|
||||||
|
|
||||||
-- mod/foo.go --
|
-- mod/foo.go --
|
||||||
|
|
@ -38,3 +52,13 @@ module .\.
|
||||||
-- badname/foo.go --
|
-- badname/foo.go --
|
||||||
package badname
|
package badname
|
||||||
|
|
||||||
|
-- dotname/go.mod --
|
||||||
|
module example.com/dotname
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
-- dotname/.dot/dot.go --
|
||||||
|
package dot
|
||||||
|
-- dotname/use/use.go --
|
||||||
|
package use
|
||||||
|
|
||||||
|
import _ "example.com/dotname/.dot"
|
||||||
|
|
|
||||||
40
src/cmd/vendor/golang.org/x/mod/module/module.go
generated
vendored
40
src/cmd/vendor/golang.org/x/mod/module/module.go
generated
vendored
|
|
@ -270,7 +270,7 @@ func fileNameOK(r rune) bool {
|
||||||
|
|
||||||
// CheckPath checks that a module path is valid.
|
// CheckPath checks that a module path is valid.
|
||||||
// A valid module path is a valid import path, as checked by CheckImportPath,
|
// A valid module path is a valid import path, as checked by CheckImportPath,
|
||||||
// with two additional constraints.
|
// with three additional constraints.
|
||||||
// First, the leading path element (up to the first slash, if any),
|
// First, the leading path element (up to the first slash, if any),
|
||||||
// by convention a domain name, must contain only lower-case ASCII letters,
|
// by convention a domain name, must contain only lower-case ASCII letters,
|
||||||
// ASCII digits, dots (U+002E), and dashes (U+002D);
|
// ASCII digits, dots (U+002E), and dashes (U+002D);
|
||||||
|
|
@ -280,8 +280,9 @@ func fileNameOK(r rune) bool {
|
||||||
// and must not contain any dots. For paths beginning with "gopkg.in/",
|
// and must not contain any dots. For paths beginning with "gopkg.in/",
|
||||||
// this second requirement is replaced by a requirement that the path
|
// this second requirement is replaced by a requirement that the path
|
||||||
// follow the gopkg.in server's conventions.
|
// follow the gopkg.in server's conventions.
|
||||||
|
// Third, no path element may begin with a dot.
|
||||||
func CheckPath(path string) error {
|
func CheckPath(path string) error {
|
||||||
if err := checkPath(path, false); err != nil {
|
if err := checkPath(path, modulePath); err != nil {
|
||||||
return fmt.Errorf("malformed module path %q: %v", path, err)
|
return fmt.Errorf("malformed module path %q: %v", path, err)
|
||||||
}
|
}
|
||||||
i := strings.Index(path, "/")
|
i := strings.Index(path, "/")
|
||||||
|
|
@ -315,7 +316,7 @@ func CheckPath(path string) error {
|
||||||
//
|
//
|
||||||
// A valid path element is a non-empty string made up of
|
// A valid path element is a non-empty string made up of
|
||||||
// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
|
// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
|
||||||
// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
|
// It must not end with a dot (U+002E), nor contain two dots in a row.
|
||||||
//
|
//
|
||||||
// The element prefix up to the first dot must not be a reserved file name
|
// The element prefix up to the first dot must not be a reserved file name
|
||||||
// on Windows, regardless of case (CON, com1, NuL, and so on). The element
|
// on Windows, regardless of case (CON, com1, NuL, and so on). The element
|
||||||
|
|
@ -326,19 +327,29 @@ func CheckPath(path string) error {
|
||||||
// top-level package documentation for additional information about
|
// top-level package documentation for additional information about
|
||||||
// subtleties of Unicode.
|
// subtleties of Unicode.
|
||||||
func CheckImportPath(path string) error {
|
func CheckImportPath(path string) error {
|
||||||
if err := checkPath(path, false); err != nil {
|
if err := checkPath(path, importPath); err != nil {
|
||||||
return fmt.Errorf("malformed import path %q: %v", path, err)
|
return fmt.Errorf("malformed import path %q: %v", path, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pathKind indicates what kind of path we're checking. Module paths,
|
||||||
|
// import paths, and file paths have different restrictions.
|
||||||
|
type pathKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
modulePath pathKind = iota
|
||||||
|
importPath
|
||||||
|
filePath
|
||||||
|
)
|
||||||
|
|
||||||
// checkPath checks that a general path is valid.
|
// checkPath checks that a general path is valid.
|
||||||
// It returns an error describing why but not mentioning path.
|
// It returns an error describing why but not mentioning path.
|
||||||
// Because these checks apply to both module paths and import paths,
|
// Because these checks apply to both module paths and import paths,
|
||||||
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
// the caller is expected to add the "malformed ___ path %q: " prefix.
|
||||||
// fileName indicates whether the final element of the path is a file name
|
// fileName indicates whether the final element of the path is a file name
|
||||||
// (as opposed to a directory name).
|
// (as opposed to a directory name).
|
||||||
func checkPath(path string, fileName bool) error {
|
func checkPath(path string, kind pathKind) error {
|
||||||
if !utf8.ValidString(path) {
|
if !utf8.ValidString(path) {
|
||||||
return fmt.Errorf("invalid UTF-8")
|
return fmt.Errorf("invalid UTF-8")
|
||||||
}
|
}
|
||||||
|
|
@ -357,35 +368,34 @@ func checkPath(path string, fileName bool) error {
|
||||||
elemStart := 0
|
elemStart := 0
|
||||||
for i, r := range path {
|
for i, r := range path {
|
||||||
if r == '/' {
|
if r == '/' {
|
||||||
if err := checkElem(path[elemStart:i], fileName); err != nil {
|
if err := checkElem(path[elemStart:i], kind); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
elemStart = i + 1
|
elemStart = i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := checkElem(path[elemStart:], fileName); err != nil {
|
if err := checkElem(path[elemStart:], kind); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkElem checks whether an individual path element is valid.
|
// checkElem checks whether an individual path element is valid.
|
||||||
// fileName indicates whether the element is a file name (not a directory name).
|
func checkElem(elem string, kind pathKind) error {
|
||||||
func checkElem(elem string, fileName bool) error {
|
|
||||||
if elem == "" {
|
if elem == "" {
|
||||||
return fmt.Errorf("empty path element")
|
return fmt.Errorf("empty path element")
|
||||||
}
|
}
|
||||||
if strings.Count(elem, ".") == len(elem) {
|
if strings.Count(elem, ".") == len(elem) {
|
||||||
return fmt.Errorf("invalid path element %q", elem)
|
return fmt.Errorf("invalid path element %q", elem)
|
||||||
}
|
}
|
||||||
if elem[0] == '.' && !fileName {
|
if elem[0] == '.' && kind == modulePath {
|
||||||
return fmt.Errorf("leading dot in path element")
|
return fmt.Errorf("leading dot in path element")
|
||||||
}
|
}
|
||||||
if elem[len(elem)-1] == '.' {
|
if elem[len(elem)-1] == '.' {
|
||||||
return fmt.Errorf("trailing dot in path element")
|
return fmt.Errorf("trailing dot in path element")
|
||||||
}
|
}
|
||||||
charOK := pathOK
|
charOK := pathOK
|
||||||
if fileName {
|
if kind == filePath {
|
||||||
charOK = fileNameOK
|
charOK = fileNameOK
|
||||||
}
|
}
|
||||||
for _, r := range elem {
|
for _, r := range elem {
|
||||||
|
|
@ -406,7 +416,7 @@ func checkElem(elem string, fileName bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileName {
|
if kind == filePath {
|
||||||
// don't check for Windows short-names in file names. They're
|
// don't check for Windows short-names in file names. They're
|
||||||
// only an issue for import paths.
|
// only an issue for import paths.
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -444,7 +454,7 @@ func checkElem(elem string, fileName bool) error {
|
||||||
// top-level package documentation for additional information about
|
// top-level package documentation for additional information about
|
||||||
// subtleties of Unicode.
|
// subtleties of Unicode.
|
||||||
func CheckFilePath(path string) error {
|
func CheckFilePath(path string) error {
|
||||||
if err := checkPath(path, true); err != nil {
|
if err := checkPath(path, filePath); err != nil {
|
||||||
return fmt.Errorf("malformed file path %q: %v", path, err)
|
return fmt.Errorf("malformed file path %q: %v", path, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -647,7 +657,7 @@ func EscapePath(path string) (escaped string, err error) {
|
||||||
// Versions are allowed to be in non-semver form but must be valid file names
|
// Versions are allowed to be in non-semver form but must be valid file names
|
||||||
// and not contain exclamation marks.
|
// and not contain exclamation marks.
|
||||||
func EscapeVersion(v string) (escaped string, err error) {
|
func EscapeVersion(v string) (escaped string, err error) {
|
||||||
if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
|
if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") {
|
||||||
return "", &InvalidVersionError{
|
return "", &InvalidVersionError{
|
||||||
Version: v,
|
Version: v,
|
||||||
Err: fmt.Errorf("disallowed version string"),
|
Err: fmt.Errorf("disallowed version string"),
|
||||||
|
|
@ -706,7 +716,7 @@ func UnescapeVersion(escaped string) (v string, err error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("invalid escaped version %q", escaped)
|
return "", fmt.Errorf("invalid escaped version %q", escaped)
|
||||||
}
|
}
|
||||||
if err := checkElem(v, true); err != nil {
|
if err := checkElem(v, filePath); err != nil {
|
||||||
return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
|
return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
|
|
|
||||||
2
src/cmd/vendor/modules.txt
vendored
2
src/cmd/vendor/modules.txt
vendored
|
|
@ -28,7 +28,7 @@ golang.org/x/arch/x86/x86asm
|
||||||
golang.org/x/crypto/ed25519
|
golang.org/x/crypto/ed25519
|
||||||
golang.org/x/crypto/ed25519/internal/edwards25519
|
golang.org/x/crypto/ed25519/internal/edwards25519
|
||||||
golang.org/x/crypto/ssh/terminal
|
golang.org/x/crypto/ssh/terminal
|
||||||
# golang.org/x/mod v0.4.2-0.20210225160341-66bf157bf5bc
|
# golang.org/x/mod v0.4.2-0.20210301144719-c8bb1bd8a2aa
|
||||||
## explicit
|
## explicit
|
||||||
golang.org/x/mod/internal/lazyregexp
|
golang.org/x/mod/internal/lazyregexp
|
||||||
golang.org/x/mod/modfile
|
golang.org/x/mod/modfile
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue