Fix various trivial problems (#36921)

* Fix #36915
* Fix #36919
* Close #36600
* Close #36601
* Fix incorrect oauth2 error message display
This commit is contained in:
wxiaoguang
2026-03-19 07:13:55 +08:00
committed by GitHub
parent d6496c6156
commit 18c65965ab
7 changed files with 27 additions and 40 deletions

2
go.mod
View File

@@ -37,6 +37,7 @@ require (
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21 github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21
github.com/chi-middleware/proxy v1.1.1 github.com/chi-middleware/proxy v1.1.1
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
github.com/dlclark/regexp2 v1.11.5
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/editorconfig/editorconfig-core-go/v2 v2.6.4 github.com/editorconfig/editorconfig-core-go/v2 v2.6.4
@@ -183,7 +184,6 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
github.com/fatih/color v1.18.0 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect

View File

@@ -9,7 +9,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"regexp"
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@@ -24,6 +23,7 @@ import (
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/dlclark/regexp2"
"xorm.io/builder" "xorm.io/builder"
) )
@@ -861,7 +861,7 @@ func GetCodeOwnersFromContent(ctx context.Context, data string) ([]*CodeOwnerRul
} }
type CodeOwnerRule struct { type CodeOwnerRule struct {
Rule *regexp.Regexp Rule *regexp2.Regexp // it supports negative lookahead, does better for end users
Negative bool Negative bool
Users []*user_model.User Users []*user_model.User
Teams []*org_model.Team Teams []*org_model.Team
@@ -877,7 +877,8 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule,
warnings := make([]string, 0) warnings := make([]string, 0)
rule.Rule, err = regexp.Compile(fmt.Sprintf("^%s$", strings.TrimPrefix(tokens[0], "!"))) expr := fmt.Sprintf("^%s$", strings.TrimPrefix(tokens[0], "!"))
rule.Rule, err = regexp2.Compile(expr, regexp2.None)
if err != nil { if err != nil {
warnings = append(warnings, fmt.Sprintf("incorrect codeowner regexp: %s", err)) warnings = append(warnings, fmt.Sprintf("incorrect codeowner regexp: %s", err))
return nil, warnings return nil, warnings

View File

@@ -402,7 +402,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
cols += "DROP COLUMN `" + col + "` CASCADE" cols += "DROP COLUMN `" + col + "` CASCADE"
} }
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
} }
case setting.Database.Type.IsMySQL(): case setting.Database.Type.IsMySQL():
// Drop indexes on columns first // Drop indexes on columns first
@@ -430,7 +430,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
cols += "DROP COLUMN `" + col + "`" cols += "DROP COLUMN `" + col + "`"
} }
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
} }
case setting.Database.Type.IsMSSQL(): case setting.Database.Type.IsMSSQL():
cols := "" cols := ""
@@ -444,27 +444,27 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
tableName, strings.ReplaceAll(cols, "`", "'")) tableName, strings.ReplaceAll(cols, "`", "'"))
constraints := make([]string, 0) constraints := make([]string, 0)
if err := sess.SQL(sql).Find(&constraints); err != nil { if err := sess.SQL(sql).Find(&constraints); err != nil {
return fmt.Errorf("Find constraints: %v", err) return fmt.Errorf("find constraints: %w", err)
} }
for _, constraint := range constraints { for _, constraint := range constraints {
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil { if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil {
return fmt.Errorf("Drop table `%s` default constraint `%s`: %v", tableName, constraint, err) return fmt.Errorf("drop table `%s` default constraint `%s`: %w", tableName, constraint, err)
} }
} }
sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))",
tableName, strings.ReplaceAll(cols, "`", "'")) tableName, strings.ReplaceAll(cols, "`", "'"))
constraints = make([]string, 0) constraints = make([]string, 0)
if err := sess.SQL(sql).Find(&constraints); err != nil { if err := sess.SQL(sql).Find(&constraints); err != nil {
return fmt.Errorf("Find constraints: %v", err) return fmt.Errorf("find constraints: %w", err)
} }
for _, constraint := range constraints { for _, constraint := range constraints {
if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil { if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil {
return fmt.Errorf("Drop index `%[2]s` on `%[1]s`: %v", tableName, constraint, err) return fmt.Errorf("drop index `%[2]s` on `%[1]s`: %[3]w", tableName, constraint, err)
} }
} }
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil { if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil {
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
} }
default: default:
log.Fatal("Unrecognized DB") log.Fatal("Unrecognized DB")

View File

@@ -96,6 +96,7 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
m[1] -= closing m[1] -= closing
} }
} else if lastChar == ';' { } else if lastChar == ';' {
// exclude HTML entity reference, e.g.: exclude " " from "http://example.com?foo=1 "
i := m[1] - 2 i := m[1] - 2
for ; i >= m[0]; i-- { for ; i >= m[0]; i-- {
if util.IsAlphaNumeric(line[i]) { if util.IsAlphaNumeric(line[i]) {
@@ -105,7 +106,7 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
} }
if i != m[1]-2 { if i != m[1]-2 {
if line[i] == '&' { if line[i] == '&' {
m[1] -= m[1] - i m[1] = i
} }
} }
} }

View File

@@ -118,7 +118,7 @@ func SignInOAuthCallback(ctx *context.Context) {
return return
} }
if err, ok := err.(*go_oauth2.RetrieveError); ok { if err, ok := err.(*go_oauth2.RetrieveError); ok {
ctx.Flash.Error("OAuth2 RetrieveError: "+err.Error(), true) ctx.Flash.Error("OAuth2 RetrieveError: " + err.Error())
ctx.Redirect(setting.AppSubURL + "/user/login") ctx.Redirect(setting.AppSubURL + "/user/login")
return return
} }

View File

@@ -95,7 +95,9 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
uniqTeams := make(map[string]*org_model.Team) uniqTeams := make(map[string]*org_model.Team)
for _, rule := range rules { for _, rule := range rules {
for _, f := range changedFiles { for _, f := range changedFiles {
if (rule.Rule.MatchString(f) && !rule.Negative) || (!rule.Rule.MatchString(f) && rule.Negative) { shouldMatch := !rule.Negative
matched, _ := rule.Rule.MatchString(f) // err only happens when timeouts, any error can be considered as not matched
if matched == shouldMatch {
for _, u := range rule.Users { for _, u := range rule.Users {
uniqUsers[u.ID] = u uniqUsers[u.ID] = u
} }

View File

@@ -61,33 +61,18 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
return nil, err return nil, err
} }
apiURL := repo.APIURL() apiURL := repo.APIURL()
apiURLLen := len(apiURL) blobURLBase := apiURL + "/git/blobs/"
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) treeURLBase := apiURL + "/git/trees/"
hashLen := objectFormat.FullLength()
const gitBlobsPath = "/git/blobs/"
blobURL := make([]byte, apiURLLen+hashLen+len(gitBlobsPath))
copy(blobURL, apiURL)
copy(blobURL[apiURLLen:], []byte(gitBlobsPath))
const gitTreePath = "/git/trees/"
treeURL := make([]byte, apiURLLen+hashLen+len(gitTreePath))
copy(treeURL, apiURL)
copy(treeURL[apiURLLen:], []byte(gitTreePath))
// copyPos is at the start of the hash
copyPos := len(treeURL) - hashLen
if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage { if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage {
perPage = setting.API.DefaultGitTreesPerPage perPage = setting.API.DefaultGitTreesPerPage
} }
if page <= 0 { page = max(page, 1)
page = 1
}
tree.Page = page tree.Page = page
tree.TotalCount = len(entries) tree.TotalCount = len(entries)
rangeStart := perPage * (page - 1) rangeStart := perPage * (page - 1) // int might overflow
if rangeStart >= len(entries) { if rangeStart < 0 || rangeStart >= len(entries) {
return tree, nil return tree, nil
} }
rangeEnd := min(rangeStart+perPage, len(entries)) rangeEnd := min(rangeStart+perPage, len(entries))
@@ -103,16 +88,14 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
tree.Entries[i].SHA = entries[e].ID.String() tree.Entries[i].SHA = entries[e].ID.String()
if entries[e].IsDir() { if entries[e].IsDir() {
copy(treeURL[copyPos:], entries[e].ID.String()) tree.Entries[i].URL = treeURLBase + entries[e].ID.String()
tree.Entries[i].URL = string(treeURL)
} else if entries[e].IsSubModule() { } else if entries[e].IsSubModule() {
// In Github Rest API Version=2022-11-28, if a tree entry is a submodule, // In GitHub Rest API Version=2022-11-28, if a tree entry is a submodule,
// its url will be returned as an empty string. // its url will be returned as an empty string.
// So the URL will be set to "" here. // So the URL will be set to "" here.
tree.Entries[i].URL = "" tree.Entries[i].URL = ""
} else { } else {
copy(blobURL[copyPos:], entries[e].ID.String()) tree.Entries[i].URL = blobURLBase + entries[e].ID.String()
tree.Entries[i].URL = string(blobURL)
} }
} }
return tree, nil return tree, nil