]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: explicitly reject module paths "go" and "toolchain"
authorMichael Matloob <matloob@golang.org>
Tue, 29 Jul 2025 18:17:33 +0000 (14:17 -0400)
committerMichael Matloob <matloob@golang.org>
Thu, 31 Jul 2025 18:00:08 +0000 (11:00 -0700)
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 <jitsu@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@google.com>
src/cmd/go/internal/modcmd/edit.go
src/cmd/go/internal/modload/init.go
src/cmd/go/internal/modload/modfile.go
src/cmd/go/testdata/script/mod_init_issue74784.txt [new file with mode: 0644]

index f73269378a11e161edadf060a125d545d02eaa7d..aafd9752a8e48766bd63db08b3de18f975421837 100644 (file)
@@ -234,7 +234,11 @@ func runEdit(ctx context.Context, cmd *base.Command, args []string) {
        }
 
        if *editModule != "" {
-               if err := module.CheckImportPath(*editModule); err != nil {
+               err := module.CheckImportPath(*editModule)
+               if err == nil {
+                       err = modload.CheckReservedModulePath(*editModule)
+               }
+               if err != nil {
                        base.Fatalf("go: invalid -module: %v", err)
                }
        }
index 3cf447e648ce4ee557998a9ff624c4da2956c368..e537fddfcd8b5b0d77c677ba9f691b7b22eea018 100644 (file)
@@ -1122,6 +1122,16 @@ func errWorkTooOld(gomod string, wf *modfile.WorkFile, goVers string) error {
                base.ShortPath(filepath.Dir(gomod)), goVers, verb, gover.FromGoWork(wf))
 }
 
+// CheckReservedModulePath checks whether the module path is a reserved module path
+// that can't be used for a user's module.
+func CheckReservedModulePath(path string) error {
+       if gover.IsToolchain(path) {
+               return errors.New("module path is reserved")
+       }
+
+       return nil
+}
+
 // CreateModFile initializes a new module by creating a go.mod file.
 //
 // If modPath is empty, CreateModFile will attempt to infer the path from the
@@ -1156,6 +1166,8 @@ func CreateModFile(ctx context.Context, modPath string) {
                        }
                }
                base.Fatal(err)
+       } else if err := CheckReservedModulePath(modPath); err != nil {
+               base.Fatalf(`go: invalid module path %q: `, modPath)
        } else if _, _, ok := module.SplitPathVersion(modPath); !ok {
                if strings.HasPrefix(modPath, "gopkg.in/") {
                        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))
index cb385c3505d57efb26c82ad14e8b8a3ecdcc8d40..04e204cc984c59429c9ec13efa1d56a69a35f029 100644 (file)
@@ -68,6 +68,8 @@ func ReadModFile(gomod string, fix modfile.VersionFixer) (data []byte, f *modfil
        if f.Module == nil {
                // No module declaration. Must add module path.
                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))
+       } else if err := CheckReservedModulePath(f.Module.Mod.Path); err != nil {
+               return nil, nil, fmt.Errorf("error reading %s: invalid module path: %q", base.ShortPath(gomod), f.Module.Mod.Path)
        }
 
        return data, f, err
diff --git a/src/cmd/go/testdata/script/mod_init_issue74784.txt b/src/cmd/go/testdata/script/mod_init_issue74784.txt
new file mode 100644 (file)
index 0000000..f786363
--- /dev/null
@@ -0,0 +1,26 @@
+# Don't allow the creation of modules with special "go" or "toolchain" paths.
+! go mod init go
+! stderr 'panic'
+stderr 'invalid module path'
+
+! go mod init toolchain
+! stderr 'panic'
+stderr 'invalid module path'
+
+# A module that contains the path element "go" is okay.
+go mod init example.com/go
+stderr 'creating new go.mod'
+
+# go mod edit won't allow a reserved module path either
+! go mod edit -module=go
+stderr 'invalid -module'
+
+# The go command should check for work modules for bad
+# names to return a proper error and avoid a panic.
+cp badmod.txt go.mod
+! go list
+! stderr panic
+stderr 'invalid module path'
+
+-- badmod.txt --
+module go