Skip to content
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ linters:
- govet
- ineffassign
- mirror
- modernize
- nakedret
- nolintlint
- perfsprint
Expand Down Expand Up @@ -55,6 +56,7 @@ linters:
disabled-checks:
- ifElseChain
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
- deprecatedComment # conflicts with go-swagger comments
revive:
severity: error
rules:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ XGO_VERSION := go-1.25.x
AIR_PACKAGE ?= github.com/air-verse/air@v1
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3
GOFUMPT_PACKAGE ?= mvdan.cc/[email protected]
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.5.0
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.0
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/[email protected]
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/[email protected]
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/[email protected]
Expand Down
4 changes: 3 additions & 1 deletion models/asymkey/ssh_key_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func parseKeyString(content string) (string, error) {
lines := strings.Split(content, "\n")
continuationLine := false

var keyContentSb strings.Builder
for _, line := range lines {
// Skip lines that:
// 1) are a continuation of the previous line,
Expand All @@ -74,9 +75,10 @@ func parseKeyString(content string) (string, error) {
if continuationLine || strings.ContainsAny(line, ":-") {
continuationLine = strings.HasSuffix(line, "\\")
} else {
keyContent += line
keyContentSb.WriteString(line)
}
}
keyContent += keyContentSb.String()

t, err := extractTypeFromBase64Key(keyContent)
if err != nil {
Expand Down
16 changes: 9 additions & 7 deletions models/perm/access/repo_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"slices"
"strings"

actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -168,7 +169,8 @@ func (p *Permission) ReadableUnitTypes() []unit.Type {
}

func (p *Permission) LogString() string {
format := "<Permission AccessMode=%s, %d Units, %d UnitsMode(s): ["
var formatSb strings.Builder
formatSb.WriteString("<Permission AccessMode=%s, %d Units, %d UnitsMode(s): [")
args := []any{p.AccessMode.ToString(), len(p.units), len(p.unitsMode)}

for i, u := range p.units {
Expand All @@ -180,19 +182,19 @@ func (p *Permission) LogString() string {
config = err.Error()
}
}
format += "\n\tunits[%d]: ID=%d RepoID=%d Type=%s Config=%s"
formatSb.WriteString("\n\tunits[%d]: ID=%d RepoID=%d Type=%s Config=%s")
args = append(args, i, u.ID, u.RepoID, u.Type.LogString(), config)
}
for key, value := range p.unitsMode {
format += "\n\tunitsMode[%-v]: %-v"
formatSb.WriteString("\n\tunitsMode[%-v]: %-v")
args = append(args, key.LogString(), value.LogString())
}
format += "\n\tanonymousAccessMode: %-v"
formatSb.WriteString("\n\tanonymousAccessMode: %-v")
args = append(args, p.anonymousAccessMode)
format += "\n\teveryoneAccessMode: %-v"
formatSb.WriteString("\n\teveryoneAccessMode: %-v")
args = append(args, p.everyoneAccessMode)
format += "\n\t]>"
return fmt.Sprintf(format, args...)
formatSb.WriteString("\n\t]>")
return fmt.Sprintf(formatSb.String(), args...)
}

func applyPublicAccessPermission(unitType unit.Type, accessMode perm_model.AccessMode, modeMap *map[unit.Type]perm_model.AccessMode) {
Expand Down
4 changes: 2 additions & 2 deletions models/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -1262,8 +1262,8 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) {
}

// Finally, if email address is the protected email address:
if strings.HasSuffix(email, "@"+setting.Service.NoReplyAddress) {
username := strings.TrimSuffix(email, "@"+setting.Service.NoReplyAddress)
if before, ok := strings.CutSuffix(email, "@"+setting.Service.NoReplyAddress); ok {
username := before
user := &User{}
has, err := db.GetEngine(ctx).Where("lower_name=?", username).Get(user)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions modules/auth/password/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,23 @@ func NewComplexity() {
}

func setupComplexity(values []string) {
var validCharsSb strings.Builder
if len(values) != 1 || values[0] != "off" {
for _, val := range values {
if complexity, ok := charComplexities[val]; ok {
validChars += complexity.ValidChars
validCharsSb.WriteString(complexity.ValidChars)
requiredList = append(requiredList, complexity)
}
}
if len(requiredList) == 0 {
// No valid character classes found; use all classes as default
for _, complexity := range charComplexities {
validChars += complexity.ValidChars
validCharsSb.WriteString(complexity.ValidChars)
requiredList = append(requiredList, complexity)
}
}
}
validChars = validCharsSb.String()
if validChars == "" {
// No complexities to check; provide a sensible default for password generation
validChars = charComplexities["lower"].ValidChars + charComplexities["upper"].ValidChars + charComplexities["digit"].ValidChars
Expand Down
6 changes: 3 additions & 3 deletions modules/git/foreachref/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ func (f Format) Parser(r io.Reader) *Parser {
// hexEscaped produces hex-escpaed characters from a string. For example, "\n\0"
// would turn into "%0a%00".
func (f Format) hexEscaped(delim []byte) string {
escaped := ""
var escapedSb strings.Builder
for i := range delim {
escaped += "%" + hex.EncodeToString([]byte{delim[i]})
escapedSb.WriteString("%" + hex.EncodeToString([]byte{delim[i]}))
}
return escaped
return escapedSb.String()
}
8 changes: 4 additions & 4 deletions modules/git/notes_nogogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,21 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
return err
}

path := ""

tree := &notes.Tree
log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)

var entry *TreeEntry
originalCommitID := commitID
var pathSb strings.Builder
for len(commitID) > 2 {
entry, err = tree.GetTreeEntryByPath(commitID)
if err == nil {
path += commitID
pathSb.WriteString(commitID)
break
}
if IsErrNotExist(err) {
tree, err = tree.SubTree(commitID[0:2])
path += commitID[0:2] + "/"
pathSb.WriteString(commitID[0:2] + "/")
commitID = commitID[2:]
}
if err != nil {
Expand All @@ -52,6 +51,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
return err
}
}
path := pathSb.String()

blob := entry.Blob()
dataRc, err := blob.DataAsync()
Expand Down
7 changes: 4 additions & 3 deletions modules/setting/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package setting

import (
"strings"
"sync"

"code.gitea.io/gitea/modules/log"
Expand All @@ -23,11 +24,11 @@ type OpenWithEditorApp struct {
type OpenWithEditorAppsType []OpenWithEditorApp

func (t OpenWithEditorAppsType) ToTextareaString() string {
ret := ""
var retSb strings.Builder
for _, app := range t {
ret += app.DisplayName + " = " + app.OpenURL + "\n"
retSb.WriteString(app.DisplayName + " = " + app.OpenURL + "\n")
}
return ret
return retSb.String()
}

func DefaultOpenWithEditorApps() OpenWithEditorAppsType {
Expand Down
16 changes: 10 additions & 6 deletions modules/setting/config_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,20 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
inKey := false
last := 0
escapeStringIndices := escapeRegex.FindAllStringIndex(encoded, -1)
var keySb strings.Builder
var sectionSb strings.Builder
for _, unescapeIdx := range escapeStringIndices {
preceding := encoded[last:unescapeIdx[0]]
if !inKey {
if splitter := strings.Index(preceding, "__"); splitter > -1 {
section += preceding[:splitter]
sectionSb.WriteString(preceding[:splitter])
inKey = true
key += preceding[splitter+2:]
keySb.WriteString(preceding[splitter+2:])
} else {
section += preceding
sectionSb.WriteString(preceding)
}
} else {
key += preceding
keySb.WriteString(preceding)
}
toDecode := encoded[unescapeIdx[0]+3 : unescapeIdx[1]-1]
decodedBytes := make([]byte, len(toDecode)/2)
Expand All @@ -69,12 +71,14 @@ func decodeEnvSectionKey(encoded string) (ok bool, section, key string) {
decodedBytes[i] = byte(byteInt)
}
if inKey {
key += string(decodedBytes)
keySb.Write(decodedBytes)
} else {
section += string(decodedBytes)
sectionSb.Write(decodedBytes)
}
last = unescapeIdx[1]
}
key = keySb.String()
section = sectionSb.String()
remaining := encoded[last:]
if !inKey {
if splitter := strings.Index(remaining, "__"); splitter > -1 {
Expand Down
9 changes: 5 additions & 4 deletions modules/templates/util_render.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,18 @@ func (ut *RenderUtils) MarkdownToHtml(input string) template.HTML { //nolint:rev
func (ut *RenderUtils) RenderLabels(labels []*issues_model.Label, repoLink string, issue *issues_model.Issue) template.HTML {
isPullRequest := issue != nil && issue.IsPull
baseLink := fmt.Sprintf("%s/%s", repoLink, util.Iif(isPullRequest, "pulls", "issues"))
htmlCode := `<span class="labels-list">`
var htmlCodeSb strings.Builder
htmlCodeSb.WriteString(`<span class="labels-list">`)
for _, label := range labels {
// Protect against nil value in labels - shouldn't happen but would cause a panic if so
if label == nil {
continue
}
link := fmt.Sprintf("%s?labels=%d", baseLink, label.ID)
htmlCode += string(ut.RenderLabelWithLink(label, template.URL(link)))
htmlCodeSb.WriteString(string(ut.RenderLabelWithLink(label, template.URL(link))))
}
htmlCode += "</span>"
return template.HTML(htmlCode)
htmlCodeSb.WriteString("</span>")
return template.HTML(htmlCodeSb.String())
}

func (ut *RenderUtils) RenderThemeItem(info *webtheme.ThemeMetaInfo, iconSize int) template.HTML {
Expand Down
7 changes: 4 additions & 3 deletions modules/timeutil/since.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,15 @@ func timeSincePro(then, now time.Time, lang translation.Locale) string {
return lang.TrString("tool.now")
}

var timeStr, diffStr string
var diffStr string
var timeStrSb strings.Builder
for {
if diff == 0 {
break
}

diff, diffStr = computeTimeDiffFloor(diff, lang)
timeStr += ", " + diffStr
timeStrSb.WriteString(", " + diffStr)
}
return strings.TrimPrefix(timeStr, ", ")
return strings.TrimPrefix(timeStrSb.String(), ", ")
}
7 changes: 4 additions & 3 deletions routers/api/packages/rubygems/rubygems.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,15 +433,16 @@ func makePackageVersionDependency(ctx *context.Context, version *packages_model.
}

func makePackageInfo(ctx *context.Context, versions []*packages_model.PackageVersion, c *cache.EphemeralCache) (string, error) {
ret := "---\n"
var retSb strings.Builder
retSb.WriteString("---\n")
for _, v := range versions {
dep, err := makePackageVersionDependency(ctx, v, c)
if err != nil {
return "", err
}
ret += dep + "\n"
retSb.WriteString(dep + "\n")
}
return ret, nil
return retSb.String(), nil
}

func makeGemFullFileName(gemName, version, platform string) string {
Expand Down
6 changes: 3 additions & 3 deletions routers/web/auth/oauth2_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,11 @@ func AuthorizeOAuth(ctx *context.Context) {
errs := binding.Errors{}
errs = form.Validate(ctx.Req, errs)
if len(errs) > 0 {
errstring := ""
var errstringSb strings.Builder
for _, e := range errs {
errstring += e.Error() + "\n"
errstringSb.WriteString(e.Error() + "\n")
}
ctx.ServerError("AuthorizeOAuth: Validate: ", fmt.Errorf("errors occurred during validation: %s", errstring))
ctx.ServerError("AuthorizeOAuth: Validate: ", fmt.Errorf("errors occurred during validation: %s", errstringSb.String()))
return
}

Expand Down
8 changes: 5 additions & 3 deletions routers/web/user/setting/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package setting
import (
"errors"
"net/http"
"strings"

asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -131,11 +132,12 @@ func KeysPost(ctx *context.Context) {
}
return
}
keyIDs := ""
var keyIDsSb strings.Builder
for _, key := range keys {
keyIDs += key.KeyID
keyIDs += ", "
keyIDsSb.WriteString(key.KeyID)
keyIDsSb.WriteString(", ")
}
keyIDs := keyIDsSb.String()
if len(keyIDs) > 0 {
keyIDs = keyIDs[:len(keyIDs)-2]
}
Expand Down
4 changes: 3 additions & 1 deletion services/gitdiff/gitdiff.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,13 +1141,15 @@ func readFileName(rd *strings.Reader) (string, bool) {
_, _ = fmt.Fscanf(rd, "%s ", &name)
char, _ := rd.ReadByte()
_ = rd.UnreadByte()
var nameSb strings.Builder
for !(char == 0 || char == '"' || char == 'b') {
var suffix string
_, _ = fmt.Fscanf(rd, "%s ", &suffix)
name += " " + suffix
nameSb.WriteString(" " + suffix)
char, _ = rd.ReadByte()
_ = rd.UnreadByte()
}
name += nameSb.String()
}
if len(name) < 2 {
log.Error("Unable to determine name from reader: reader=%+v", rd)
Expand Down
10 changes: 5 additions & 5 deletions services/webhook/dingtalk.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,22 @@ func (dc dingtalkConvertor) Push(p *api.PushPayload) (DingtalkPayload, error) {

title := fmt.Sprintf("[%s:%s] %s", p.Repo.FullName, branchName, commitDesc)

var text string
// for each commit, generate attachment text
var textSb strings.Builder
for i, commit := range p.Commits {
var authorName string
if commit.Author != nil {
authorName = " - " + commit.Author.Name
}
text += fmt.Sprintf("[%s](%s) %s", commit.ID[:7], commit.URL,
strings.TrimRight(commit.Message, "\r\n")) + authorName
textSb.WriteString(fmt.Sprintf("[%s](%s) %s", commit.ID[:7], commit.URL,
strings.TrimRight(commit.Message, "\r\n")) + authorName)
// add linebreak to each commit but the last
if i < len(p.Commits)-1 {
text += "\r\n"
textSb.WriteString("\r\n")
}
}

return createDingtalkPayload(title, text, linkText, titleLink), nil
return createDingtalkPayload(title, textSb.String(), linkText, titleLink), nil
}

// Issue implements PayloadConvertor Issue method
Expand Down
Loading