From 3115c9c4f0b0f917d0c4a101bf4da29dad0cafa5 Mon Sep 17 00:00:00 2001 From: Rafael Affonso Date: Sat, 16 May 2026 16:05:35 -0300 Subject: [PATCH] cmd/go/internal/doc: reject meta packages in go doc Meta-package names such as std, cmd, tool, work, and all are package patterns that expand to multiple packages, not single documentable packages. Today go doc std can fall through package resolution and print documentation for an unrelated first match such as archive/tar. Reject these names when they are the first argument to go doc, including the two-argument form such as go doc std Foo. Keep go doc -http std routing to the standard library page. Fixes #53446 Change-Id: Iaf76b2be6fec0efa6f601b7959f4bcaac7ab776d --- src/cmd/go/internal/doc/doc.go | 6 ++++++ src/cmd/go/internal/doc/doc_test.go | 25 +++++++++++++++++++++++++ src/cmd/go/testdata/script/doc.txt | 18 ++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/cmd/go/internal/doc/doc.go b/src/cmd/go/internal/doc/doc.go index 32f4674ef030c8..c1fed53157e83b 100644 --- a/src/cmd/go/internal/doc/doc.go +++ b/src/cmd/go/internal/doc/doc.go @@ -233,12 +233,18 @@ func do(ctx context.Context, writer io.Writer, flagSet *flag.FlagSet, args []str // Outside a module or workspace, go to the documentation for the standard library. return doPkgsite(ctx, "std", "") } + if args := flagSet.Args(); len(args) == 1 && args[0] == "std" { + return doPkgsite(ctx, "std", "") + } // If args are provided, we need to figure out which page to open on the pkgsite // instance. Run the logic below to determine a match for a symbol, method, // or field, but don't actually print the documentation to the output. writer = io.Discard } + if a := flagSet.Args(); len(a) > 0 && search.IsMetaPackage(a[0]) { + return fmt.Errorf("go doc does not support meta-package argument %s", a[0]) + } var paths []string var symbol, method string // Loop until something is printed. diff --git a/src/cmd/go/internal/doc/doc_test.go b/src/cmd/go/internal/doc/doc_test.go index cd931e33c0f0c7..2d0854c4bdd566 100644 --- a/src/cmd/go/internal/doc/doc_test.go +++ b/src/cmd/go/internal/doc/doc_test.go @@ -1239,6 +1239,31 @@ func TestNoPackageClauseWhenNoMatch(t *testing.T) { } } +func TestMetaPackage(t *testing.T) { + maybeSkip(t) + for _, args := range [][]string{ + {"std"}, + {"cmd"}, + {"all"}, + {"tool"}, + {"work"}, + {"std", "Foo"}, + } { + var b strings.Builder + var flagSet flag.FlagSet + err := do(t.Context(), &b, &flagSet, args) + if err == nil { + t.Fatalf("expected error for go doc %s; got output:\n%s", strings.Join(args, " "), b.String()) + } + if want := "go doc does not support meta-package argument " + args[0]; !strings.Contains(err.Error(), want) { + t.Fatalf("unexpected error for go doc %s: %v", strings.Join(args, " "), err) + } + if b.Len() != 0 { + t.Fatalf("go doc %s produced unexpected output:\n%s", strings.Join(args, " "), b.String()) + } + } +} + type trimTest struct { path string prefix string diff --git a/src/cmd/go/testdata/script/doc.txt b/src/cmd/go/testdata/script/doc.txt index 3ff1aab093ee37..2d1901c90dc7b7 100644 --- a/src/cmd/go/testdata/script/doc.txt +++ b/src/cmd/go/testdata/script/doc.txt @@ -60,6 +60,24 @@ stdout . go doc Method stdout . +# Meta packages are package patterns, not documentable packages. +# Regression test for golang.org/issue/53446. +! go doc std +stderr '^doc: go doc does not support meta-package argument std$' +! stdout . + +! go doc all +stderr '^doc: go doc does not support meta-package argument all$' +! stdout . + +! go doc std Foo +stderr '^doc: go doc does not support meta-package argument std$' +! stdout . + +env TEST_GODOC_URL_FILE=$WORK/url.txt +go doc -http std +grep '/std' $TEST_GODOC_URL_FILE + -- go.mod -- module p/v2