]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/work: avoid panic for a repeated //go:debug setting
authorAndrew W. Phillips <aphillips801@gmail.com>
Tue, 29 Aug 2023 10:55:59 +0000 (20:55 +1000)
committerGopher Robot <gobot@golang.org>
Mon, 10 Jun 2024 14:46:37 +0000 (14:46 +0000)
The creation of a bytes.Buffer in one code path is missing causing a nil
pointer dereference.

Changed (as rec. by Bryan Mills) to use fmt.Appendf() on []byte instead of
fmt.Fprintf on *bytes.Buffer - simpler and avoids duplicated code (but
requires Go 1.19 or later).

Added test to verify the change (as rec. by Michael Matloob) at
src\cmd\go\testdata\script\build_repeated_godebug_issue62346.txt

Fixes #62346

Change-Id: Ic3267d878a6f7ebedb1cde64e6206de404176b10
Reviewed-on: https://go-review.googlesource.com/c/go/+/523836
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Michael Matloob <matloob@golang.org>

src/cmd/go/internal/work/exec.go
src/cmd/go/testdata/script/build_repeated_godebug_issue62346.txt [new file with mode: 0644]

index 90c61a9c30754588d38a656f55b1f2597b496bc6..8dd9802f4f01a82dcdc7063f89e0d023536289a2 100644 (file)
@@ -989,21 +989,18 @@ OverlayLoop:
 }
 
 func (b *Builder) checkDirectives(a *Action) error {
-       var msg *bytes.Buffer
+       var msg []byte
        p := a.Package
        var seen map[string]token.Position
        for _, d := range p.Internal.Build.Directives {
                if strings.HasPrefix(d.Text, "//go:debug") {
                        key, _, err := load.ParseGoDebug(d.Text)
                        if err != nil && err != load.ErrNotGoDebug {
-                               if msg == nil {
-                                       msg = new(bytes.Buffer)
-                               }
-                               fmt.Fprintf(msg, "%s: invalid //go:debug: %v\n", d.Pos, err)
+                               msg = fmt.Appendf(msg, "%s: invalid //go:debug: %v\n", d.Pos, err)
                                continue
                        }
                        if pos, ok := seen[key]; ok {
-                               fmt.Fprintf(msg, "%s: repeated //go:debug for %v\n\t%s: previous //go:debug\n", d.Pos, key, pos)
+                               msg = fmt.Appendf(msg, "%s: repeated //go:debug for %v\n\t%s: previous //go:debug\n", d.Pos, key, pos)
                                continue
                        }
                        if seen == nil {
@@ -1012,12 +1009,12 @@ func (b *Builder) checkDirectives(a *Action) error {
                        seen[key] = d.Pos
                }
        }
-       if msg != nil {
+       if len(msg) > 0 {
                // We pass a non-nil error to reportCmd to trigger the failure reporting
                // path, but the content of the error doesn't matter because msg is
                // non-empty.
                err := errors.New("invalid directive")
-               return b.Shell(a).reportCmd("", "", msg.Bytes(), err)
+               return b.Shell(a).reportCmd("", "", msg, err)
        }
        return nil
 }
diff --git a/src/cmd/go/testdata/script/build_repeated_godebug_issue62346.txt b/src/cmd/go/testdata/script/build_repeated_godebug_issue62346.txt
new file mode 100644 (file)
index 0000000..23534dd
--- /dev/null
@@ -0,0 +1,14 @@
+[short] skip # runs go build
+! go build file.go
+! stderr 'panic:'
+! stderr 'runtime error'
+stderr 'file.go:2:1: repeated //go:debug for panicnil'
+
+-- file.go --
+//go:debug panicnil=1
+//go:debug panicnil=1
+
+package main
+
+func main() {
+}