Skip to content

Commit c0ee2fd

Browse files
committed
cmd/go: explicitly reject module paths "go" and "toolchain"
The module paths "go" and "toolchain" are reserved for the dependency on the go and toolchain versions. Check for those paths in go mod init to create modules, go mod edit, and in the module loader and return an error when attempting to use those paths for a work module. Trying to init or load a work module with a go.mod that specifies the module path "go" panics since Go 1.21 (when the toolchain switching logic and the implicit dependencies on the "go" module was introduced), and this change returns a proper error instead of panicking. Fixes #74784 Change-Id: I10e712f8fddbea63edaeb37e14c6d783722e623f Reviewed-on: https://go-review.googlesource.com/c/go/+/691515 Reviewed-by: Ian Alexander <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent a4d9977 commit c0ee2fd

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed

src/cmd/go/internal/modcmd/edit.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,11 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
234234
}
235235

236236
if *editModule != "" {
237-
if err := module.CheckImportPath(*editModule); err != nil {
237+
err := module.CheckImportPath(*editModule)
238+
if err == nil {
239+
err = modload.CheckReservedModulePath(*editModule)
240+
}
241+
if err != nil {
238242
base.Fatalf("go: invalid -module: %v", err)
239243
}
240244
}

src/cmd/go/internal/modload/init.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,16 @@ func errWorkTooOld(gomod string, wf *modfile.WorkFile, goVers string) error {
11221122
base.ShortPath(filepath.Dir(gomod)), goVers, verb, gover.FromGoWork(wf))
11231123
}
11241124

1125+
// CheckReservedModulePath checks whether the module path is a reserved module path
1126+
// that can't be used for a user's module.
1127+
func CheckReservedModulePath(path string) error {
1128+
if gover.IsToolchain(path) {
1129+
return errors.New("module path is reserved")
1130+
}
1131+
1132+
return nil
1133+
}
1134+
11251135
// CreateModFile initializes a new module by creating a go.mod file.
11261136
//
11271137
// If modPath is empty, CreateModFile will attempt to infer the path from the
@@ -1156,6 +1166,8 @@ func CreateModFile(ctx context.Context, modPath string) {
11561166
}
11571167
}
11581168
base.Fatal(err)
1169+
} else if err := CheckReservedModulePath(modPath); err != nil {
1170+
base.Fatalf(`go: invalid module path %q: `, modPath)
11591171
} else if _, _, ok := module.SplitPathVersion(modPath); !ok {
11601172
if strings.HasPrefix(modPath, "gopkg.in/") {
11611173
invalidMajorVersionMsg := fmt.Errorf("module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN:\n\tgo mod init %s", suggestGopkgIn(modPath))

src/cmd/go/internal/modload/modfile.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ func ReadModFile(gomod string, fix modfile.VersionFixer) (data []byte, f *modfil
6868
if f.Module == nil {
6969
// No module declaration. Must add module path.
7070
return nil, nil, fmt.Errorf("error reading %s: missing module declaration. To specify the module path:\n\tgo mod edit -module=example.com/mod", base.ShortPath(gomod))
71+
} else if err := CheckReservedModulePath(f.Module.Mod.Path); err != nil {
72+
return nil, nil, fmt.Errorf("error reading %s: invalid module path: %q", base.ShortPath(gomod), f.Module.Mod.Path)
7173
}
7274

7375
return data, f, err
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Don't allow the creation of modules with special "go" or "toolchain" paths.
2+
! go mod init go
3+
! stderr 'panic'
4+
stderr 'invalid module path'
5+
6+
! go mod init toolchain
7+
! stderr 'panic'
8+
stderr 'invalid module path'
9+
10+
# A module that contains the path element "go" is okay.
11+
go mod init example.com/go
12+
stderr 'creating new go.mod'
13+
14+
# go mod edit won't allow a reserved module path either
15+
! go mod edit -module=go
16+
stderr 'invalid -module'
17+
18+
# The go command should check for work modules for bad
19+
# names to return a proper error and avoid a panic.
20+
cp badmod.txt go.mod
21+
! go list
22+
! stderr panic
23+
stderr 'invalid module path'
24+
25+
-- badmod.txt --
26+
module go

0 commit comments

Comments
 (0)