~rjarry/aerc

2d6b2c0e7bee7a029fe97617ef870208937a39d3 — Tristan Partin 24 days ago 71dc0c0
lint: update golangci-lint to 1.61.0

golangci-lint 1.56 does not work with go 1.23. It causes obscure errors:

[linters_context/goanalysis] buildir: panic during analysis:
Cannot range over: func(yield func(K, V) bool), goroutine 4743 [running]: runtime/debug.Stack()
	/usr/lib/go/src/runtime/debug/stack.go:26 +0x5e
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func1()
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_action.go:104 +0x5a
panic({0x164b260?, 0xc00669b4a0?})
	/usr/lib/go/src/runtime/panic.go:785 +0x132
honnef.co/go/tools/go/ir.(*builder).rangeStmt(0xc000051910, 0xc00a29cf00, 0xc009bf55c0, 0x0, {0x1af1960, 0xc009bf55c0})
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2214 +0x894
honnef.co/go/tools/go/ir.(*builder).stmt(0xc000051910, 0xc00a29cf00, {0x1af6970?, 0xc009bf55c0?})
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2427 +0x20a
honnef.co/go/tools/go/ir.(*builder).stmtList(...)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:847
honnef.co/go/tools/go/ir.(*builder).stmt(0xc000051910, 0xc00a29cf00, {0x1af6880?, 0xc004f52ed0?})
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2385 +0x1415
honnef.co/go/tools/go/ir.(*builder).buildFunction(0xc000051910, 0xc00a29cf00)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2497 +0x417
honnef.co/go/tools/go/ir.(*builder).buildFuncDecl(0xc000051910, 0xc00622eea0, 0xc004f52f00)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2534 +0x189
honnef.co/go/tools/go/ir.(*Package).build(0xc00622eea0)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2638 +0xb46
sync.(*Once).doSlow(0xc009b81260?, 0xc009bf5bc0?)
	/usr/lib/go/src/sync/once.go:76 +0xb4
sync.(*Once).Do(...)
	/usr/lib/go/src/sync/once.go:67
honnef.co/go/tools/go/ir.(*Package).Build(...)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/go/ir/builder.go:2556
honnef.co/go/tools/internal/passes/buildir.run(0xc000cf61a0)
	/home/build/go/pkg/mod/honnef.co/go/tools@v0.4.6/internal/passes/buildir/buildir.go:86 +0x18b
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyze(0xc002d77d70)
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_action.go:190 +0x9cd
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func2()
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_action.go:112 +0x17
github.com/golangci/golangci-lint/pkg/timeutils.(*Stopwatch).TrackStage(0xc0007a5c70, {0x1859190, 0x7}, 0xc001c28f48)
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/timeutils/stopwatch.go:111 +0x44
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe(0xc00212f680?)
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_action.go:111 +0x6e
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze.func2(0xc002d77d70)
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_loadingpackage.go:80 +0xa5
created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze in goroutine 3468
	/home/build/go/pkg/mod/github.com/golangci/golangci-lint@v1.56.1/pkg/golinters/goanalysis/runner_loadingpackage.go:75 +0x1e9

Update golangci-lint to 1.61.0 that works with go 1.23. It has new
checkers that report errors that we need to fix:

lib/crypto/gpg/gpgbin/gpgbin.go:226:22: printf: non-constant format string in call to fmt.Errorf (govet)
			return fmt.Errorf(strings.TrimPrefix(line, "[GNUPG:] "))
			                  ^
worker/imap/observer.go:142:21: printf: non-constant format string in call to fmt.Errorf (govet)
		Error: fmt.Errorf(errMsg),
		                  ^
app/dirlist.go:409:5: S1009: should omit nil check; len() for []string is defined as zero (gosimple)
	if dirlist.dirs == nil || len(dirlist.dirs) == 0 {
	   ^
app/dirtree.go:181:5: S1009: should omit nil check; len() for []*git.sr.ht/~rjarry/aerc/worker/types.Thread is defined as zero (gosimple)
	if dt.list == nil || len(dt.list) == 0 || dt.countVisible(dt.list) < y+dt.Scroll() {
	   ^
app/authinfo.go:30:34: printf: non-constant format string in call to (*git.sr.ht/~rjarry/aerc/lib/ui.Context).Printf (govet)
		ctx.Printf(0, 0, defaultStyle, text)
		                               ^
app/authinfo.go:34:27: printf: non-constant format string in call to (*git.sr.ht/~rjarry/aerc/lib/ui.Context).Printf (govet)
		ctx.Printf(0, 0, style, text)
		                        ^
app/authinfo.go:62:34: printf: non-constant format string in call to (*git.sr.ht/~rjarry/aerc/lib/ui.Context).Printf (govet)
				x += ctx.Printf(x, 0, style, text)
				                             ^

Pretty much all of these errors are us passing non-const format strings
to various methods. In C land, this is a large security issue. I would
assume the same stands in Go. Thank you golangci-lint!

Link: https://builds.sr.ht/~rjarry/job/1332376#task-validate-500
Signed-off-by: Tristan Partin <tristan@partin.io>
Acked-by: Robin Jarry <robin@jarry.cc>
M GNUmakefile => GNUmakefile +1 -1
@@ 56,7 56,7 @@ lint:
	@$(GO) run mvdan.cc/gofumpt@$(gofumpt_tag) -d . | grep ^ \
		&& echo The above files need to be formatted, please run make fmt && exit 1 \
		|| echo all files formatted.
	$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.1 run \
	$(GO) run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 run \
		$$(echo $(GOFLAGS) | sed s/-tags=/--build-tags=/)
	$(GO) run $(GOFLAGS) contrib/linters.go ./...


M app/authinfo.go => app/authinfo.go +4 -6
@@ 1,8 1,6 @@
package app

import (
	"fmt"

	"git.sr.ht/~rjarry/aerc/config"
	"git.sr.ht/~rjarry/aerc/lib/auth"
	"git.sr.ht/~rjarry/aerc/lib/ui"


@@ 27,11 25,11 @@ func (a *AuthInfo) Draw(ctx *ui.Context) {
	switch {
	case a.authdetails == nil:
		text = "(no header)"
		ctx.Printf(0, 0, defaultStyle, text)
		ctx.Printf(0, 0, defaultStyle, "%s", text)
	case a.authdetails.Err != nil:
		style := a.uiConfig.GetStyle(config.STYLE_ERROR)
		text = a.authdetails.Err.Error()
		ctx.Printf(0, 0, style, text)
		ctx.Printf(0, 0, style, "%s", text)
	default:
		checkBounds := func(x int) bool {
			return x < ctx.Width()


@@ 59,7 57,7 @@ func (a *AuthInfo) Draw(ctx *ui.Context) {
				if i > 0 {
					text = " " + text
				}
				x += ctx.Printf(x, 0, style, text)
				x += ctx.Printf(x, 0, style, "%s", text)
			}
		}
		if a.showInfo {


@@ 76,7 74,7 @@ func (a *AuthInfo) Draw(ctx *ui.Context) {
			if checkBounds(x) && infoText != "" {
				if trunc := ctx.Width() - x - 3; trunc > 0 {
					text = runewidth.Truncate(infoText, trunc, "…")
					ctx.Printf(x, 0, defaultStyle, fmt.Sprintf(" (%s)", text))
					ctx.Printf(x, 0, defaultStyle, " (%s)", text)
				}
			}
		}

M app/dirlist.go => app/dirlist.go +2 -2
@@ 255,7 255,7 @@ func (dirlist *DirectoryList) Draw(ctx *ui.Context) {

	if len(dirlist.dirs) == 0 {
		style := uiConfig.GetStyle(config.STYLE_DIRLIST_DEFAULT)
		ctx.Printf(0, 0, style, uiConfig.EmptyDirlist)
		ctx.Printf(0, 0, style, "%s", uiConfig.EmptyDirlist)
		return
	}



@@ 406,7 406,7 @@ func (dirlist *DirectoryList) MouseEvent(localX int, localY int, event vaxis.Eve
}

func (dirlist *DirectoryList) Clicked(x int, y int) (string, bool) {
	if dirlist.dirs == nil || len(dirlist.dirs) == 0 {
	if len(dirlist.dirs) == 0 {
		return "", false
	}
	for i, name := range dirlist.dirs {

M app/dirtree.go => app/dirtree.go +2 -2
@@ 99,7 99,7 @@ func (dt *DirectoryTree) Draw(ctx *ui.Context) {
	n := dt.countVisible(dt.list)
	if n == 0 || dt.listIdx < 0 {
		style := uiConfig.GetStyle(config.STYLE_DIRLIST_DEFAULT)
		ctx.Printf(0, 0, style, uiConfig.EmptyDirlist)
		ctx.Printf(0, 0, style, "%s", uiConfig.EmptyDirlist)
		return
	}



@@ 178,7 178,7 @@ func (dt *DirectoryTree) MouseEvent(localX int, localY int, event vaxis.Event) {
}

func (dt *DirectoryTree) Clicked(x int, y int) (string, bool) {
	if dt.list == nil || len(dt.list) == 0 || dt.countVisible(dt.list) < y+dt.Scroll() {
	if len(dt.list) == 0 || dt.countVisible(dt.list) < y+dt.Scroll() {
		return "", false
	}
	visible := 0

M app/getpasswd.go => app/getpasswd.go +1 -1
@@ 35,7 35,7 @@ func (gp *GetPasswd) Draw(ctx *ui.Context) {
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', defaultStyle)
	ctx.Fill(0, 0, ctx.Width(), 1, ' ', titleStyle)
	ctx.Printf(1, 0, titleStyle, "%s", gp.title)
	ctx.Printf(1, 1, defaultStyle, gp.prompt)
	ctx.Printf(1, 1, defaultStyle, "%s", gp.prompt)
	gp.input.Draw(ctx.Subcontext(1, 3, ctx.Width()-2, 1))
}


M app/listbox.go => app/listbox.go +3 -5
@@ 1,7 1,6 @@
package app

import (
	"fmt"
	"math"
	"strings"
	"sync"


@@ 98,9 97,8 @@ func (lb *ListBox) Draw(ctx *ui.Context) {
	y := 0
	if lb.showFilterField() {
		y = 1
		x := ctx.Printf(0, y, defaultStyle,
			fmt.Sprintf("Filter (%d/%d): ",
				len(lb.filtered()), len(lb.lines)))
		x := ctx.Printf(0, y, defaultStyle, "Filter (%d/%d): ",
			len(lb.filtered()), len(lb.lines))
		lb.filter.Draw(ctx.Subcontext(x, y, w-x, 1))
	}



@@ 200,7 198,7 @@ func (lb *ListBox) drawBox(ctx *ui.Context) {
				}
			}
		}
		ctx.Printf(1, y, style, line)
		ctx.Printf(1, y, style, "%s", line)
		y += 1
	}


M app/pgpinfo.go => app/pgpinfo.go +1 -1
@@ 53,7 53,7 @@ func (p *PGPInfo) DrawSignature(ctx *ui.Context) {
	}

	x := ctx.Printf(0, 0, indicatorStyle, "%s %s ", icon, indicatorText)
	ctx.Printf(x, 0, textstyle, messageText)
	ctx.Printf(x, 0, textstyle, "%s", messageText)
}

func (p *PGPInfo) DrawEncryption(ctx *ui.Context, y int) {

M lib/crypto/gpg/gpgbin/gpgbin.go => lib/crypto/gpg/gpgbin/gpgbin.go +1 -1
@@ 223,7 223,7 @@ func parse(r io.Reader, md *models.MessageDetails) error {
		case "NODATA":
			md.SignatureError = "gpg: no signature packet found"
		case "FAILURE":
			return fmt.Errorf(strings.TrimPrefix(line, "[GNUPG:] "))
			return fmt.Errorf("%s", strings.TrimPrefix(line, "[GNUPG:] "))
		}
	}
	md.Body = bytes.NewReader(msgContent)

M worker/imap/observer.go => worker/imap/observer.go +1 -1
@@ 139,7 139,7 @@ func (o *observer) emit(errMsg string) {
		Message: types.RespondTo(&types.Disconnect{}),
	}, nil)
	o.worker.PostMessage(&types.ConnError{
		Error: fmt.Errorf(errMsg),
		Error: fmt.Errorf("%s", errMsg),
	}, nil)
}