Skip to content

Commit f515c1b

Browse files
AndrewWPhillipsgopherbot
authored andcommitted
cmd/go/internal/work: avoid panic for a repeated //go:debug setting
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>
1 parent da65071 commit f515c1b

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

src/cmd/go/internal/work/exec.go

+5-8
Original file line numberDiff line numberDiff line change
@@ -989,21 +989,18 @@ OverlayLoop:
989989
}
990990

991991
func (b *Builder) checkDirectives(a *Action) error {
992-
var msg *bytes.Buffer
992+
var msg []byte
993993
p := a.Package
994994
var seen map[string]token.Position
995995
for _, d := range p.Internal.Build.Directives {
996996
if strings.HasPrefix(d.Text, "//go:debug") {
997997
key, _, err := load.ParseGoDebug(d.Text)
998998
if err != nil && err != load.ErrNotGoDebug {
999-
if msg == nil {
1000-
msg = new(bytes.Buffer)
1001-
}
1002-
fmt.Fprintf(msg, "%s: invalid //go:debug: %v\n", d.Pos, err)
999+
msg = fmt.Appendf(msg, "%s: invalid //go:debug: %v\n", d.Pos, err)
10031000
continue
10041001
}
10051002
if pos, ok := seen[key]; ok {
1006-
fmt.Fprintf(msg, "%s: repeated //go:debug for %v\n\t%s: previous //go:debug\n", d.Pos, key, pos)
1003+
msg = fmt.Appendf(msg, "%s: repeated //go:debug for %v\n\t%s: previous //go:debug\n", d.Pos, key, pos)
10071004
continue
10081005
}
10091006
if seen == nil {
@@ -1012,12 +1009,12 @@ func (b *Builder) checkDirectives(a *Action) error {
10121009
seen[key] = d.Pos
10131010
}
10141011
}
1015-
if msg != nil {
1012+
if len(msg) > 0 {
10161013
// We pass a non-nil error to reportCmd to trigger the failure reporting
10171014
// path, but the content of the error doesn't matter because msg is
10181015
// non-empty.
10191016
err := errors.New("invalid directive")
1020-
return b.Shell(a).reportCmd("", "", msg.Bytes(), err)
1017+
return b.Shell(a).reportCmd("", "", msg, err)
10211018
}
10221019
return nil
10231020
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[short] skip # runs go build
2+
! go build file.go
3+
! stderr 'panic:'
4+
! stderr 'runtime error'
5+
stderr 'file.go:2:1: repeated //go:debug for panicnil'
6+
7+
-- file.go --
8+
//go:debug panicnil=1
9+
//go:debug panicnil=1
10+
11+
package main
12+
13+
func main() {
14+
}

0 commit comments

Comments
 (0)