Skip to content

Commit 03c18e8

Browse files
authored
Merge branch 'main' into fix-user-project-menu
2 parents 48b98c7 + f938dbc commit 03c18e8

File tree

85 files changed

+2120
-1741
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+2120
-1741
lines changed

cmd/admin_auth_ldap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
386386
return a.createAuthSource(ctx, authSource)
387387
}
388388

389-
// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
389+
// updateLdapSimpleAuth updates a new LDAP (simple auth) authentication source.
390390
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
391391
ctx, cancel := installSignals()
392392
defer cancel()

contrib/backport/backport.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ func main() {
6464
Value: "",
6565
Usage: "Forked user name on Github",
6666
},
67+
&cli.StringFlag{
68+
Name: "gh-access-token",
69+
Value: "",
70+
Usage: "Access token for GitHub api request",
71+
},
6772
&cli.BoolFlag{
6873
Name: "no-fetch",
6974
Usage: "Set this flag to prevent fetch of remote branches",
@@ -169,9 +174,10 @@ func runBackport(c *cli.Context) error {
169174
fmt.Printf("* Backporting %s to %s as %s\n", pr, localReleaseBranch, backportBranch)
170175

171176
sha := c.String("cherry-pick")
177+
accessToken := c.String("gh-access-token")
172178
if sha == "" {
173179
var err error
174-
sha, err = determineSHAforPR(ctx, pr)
180+
sha, err = determineSHAforPR(ctx, pr, accessToken)
175181
if err != nil {
176182
return err
177183
}
@@ -427,13 +433,16 @@ func readVersion() string {
427433
return strings.Join(split[:2], ".")
428434
}
429435

430-
func determineSHAforPR(ctx context.Context, prStr string) (string, error) {
436+
func determineSHAforPR(ctx context.Context, prStr, accessToken string) (string, error) {
431437
prNum, err := strconv.Atoi(prStr)
432438
if err != nil {
433439
return "", err
434440
}
435441

436442
client := github.NewClient(http.DefaultClient)
443+
if accessToken != "" {
444+
client = client.WithAuthToken(accessToken)
445+
}
437446

438447
pr, _, err := client.PullRequests.Get(ctx, "go-gitea", "gitea", prNum)
439448
if err != nil {

custom/conf/app.example.ini

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ RUN_USER = ; git
324324
;; Maximum number of locks returned per page
325325
;LFS_LOCKS_PAGING_NUM = 50
326326
;;
327+
;; When clients make lfs batch requests, reject them if there are more pointers than this number
328+
;; zero means 'unlimited'
329+
;LFS_MAX_BATCH_SIZE = 0
330+
;;
327331
;; Allow graceful restarts using SIGHUP to fork
328332
;ALLOW_GRACEFUL_RESTARTS = true
329333
;;
@@ -907,6 +911,24 @@ LEVEL = Info
907911
;; Valid site url schemes for user profiles
908912
;VALID_SITE_URL_SCHEMES=http,https
909913

914+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
915+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
916+
;[service.explore]
917+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
918+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
919+
;;
920+
;; Only allow signed in users to view the explore pages.
921+
;REQUIRE_SIGNIN_VIEW = false
922+
;;
923+
;; Disable the users explore page.
924+
;DISABLE_USERS_PAGE = false
925+
;;
926+
;; Disable the organizations explore page.
927+
;DISABLE_ORGANIZATIONS_PAGE = false
928+
;;
929+
;; Disable the code explore page.
930+
;DISABLE_CODE_PAGE = false
931+
;;
910932

911933
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
912934
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2620,6 +2642,10 @@ LEVEL = Info
26202642
;; override the azure blob base path if storage type is azureblob
26212643
;AZURE_BLOB_BASE_PATH = lfs/
26222644

2645+
;[lfs_client]
2646+
;; When mirroring an upstream lfs endpoint, limit the number of pointers in each batch request to this number
2647+
;BATCH_SIZE = 20
2648+
26232649
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26242650
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26252651
;; settings for packages, will override storage setting

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ require (
5454
github.com/go-chi/chi/v5 v5.0.13
5555
github.com/go-chi/cors v1.2.1
5656
github.com/go-co-op/gocron v1.37.0
57-
github.com/go-enry/go-enry/v2 v2.8.8
57+
github.com/go-enry/go-enry/v2 v2.9.1
5858
github.com/go-git/go-billy/v5 v5.5.0
5959
github.com/go-git/go-git/v5 v5.12.0
6060
github.com/go-ldap/ldap/v3 v3.4.6

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
315315
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
316316
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
317317
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
318-
github.com/go-enry/go-enry/v2 v2.8.8 h1:EhfxWpw4DQ3WEFB1Y77X8vKqZL0D0EDUUWYDUAIv9/4=
319-
github.com/go-enry/go-enry/v2 v2.8.8/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
318+
github.com/go-enry/go-enry/v2 v2.9.1 h1:G9iDteJ/Mc0F4Di5NeQknf83R2OkRbwY9cAYmcqVG6U=
319+
github.com/go-enry/go-enry/v2 v2.9.1/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
320320
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
321321
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
322322
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=

models/actions/artifact.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
6969
OwnerID: t.OwnerID,
7070
CommitSHA: t.CommitSHA,
7171
Status: int64(ArtifactStatusUploadPending),
72-
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + 3600*24*expiredDays),
72+
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
7373
}
7474
if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
7575
return nil, err
@@ -78,6 +78,13 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
7878
} else if err != nil {
7979
return nil, err
8080
}
81+
82+
if _, err := db.GetEngine(ctx).ID(artifact.ID).Cols("expired_unix").Update(&ActionArtifact{
83+
ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
84+
}); err != nil {
85+
return nil, err
86+
}
87+
8188
return artifact, nil
8289
}
8390

models/db/context.go

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ package db
66
import (
77
"context"
88
"database/sql"
9+
"errors"
10+
"runtime"
11+
"slices"
12+
"sync"
13+
14+
"code.gitea.io/gitea/modules/setting"
915

1016
"xorm.io/builder"
1117
"xorm.io/xorm"
@@ -15,76 +21,90 @@ import (
1521
// will be overwritten by Init with HammerContext
1622
var DefaultContext context.Context
1723

18-
// contextKey is a value for use with context.WithValue.
19-
type contextKey struct {
20-
name string
21-
}
24+
type engineContextKeyType struct{}
2225

23-
// enginedContextKey is a context key. It is used with context.Value() to get the current Engined for the context
24-
var (
25-
enginedContextKey = &contextKey{"engined"}
26-
_ Engined = &Context{}
27-
)
26+
var engineContextKey = engineContextKeyType{}
2827

2928
// Context represents a db context
3029
type Context struct {
3130
context.Context
32-
e Engine
33-
transaction bool
34-
}
35-
36-
func newContext(ctx context.Context, e Engine, transaction bool) *Context {
37-
return &Context{
38-
Context: ctx,
39-
e: e,
40-
transaction: transaction,
41-
}
42-
}
43-
44-
// InTransaction if context is in a transaction
45-
func (ctx *Context) InTransaction() bool {
46-
return ctx.transaction
31+
engine Engine
4732
}
4833

49-
// Engine returns db engine
50-
func (ctx *Context) Engine() Engine {
51-
return ctx.e
34+
func newContext(ctx context.Context, e Engine) *Context {
35+
return &Context{Context: ctx, engine: e}
5236
}
5337

5438
// Value shadows Value for context.Context but allows us to get ourselves and an Engined object
5539
func (ctx *Context) Value(key any) any {
56-
if key == enginedContextKey {
40+
if key == engineContextKey {
5741
return ctx
5842
}
5943
return ctx.Context.Value(key)
6044
}
6145

6246
// WithContext returns this engine tied to this context
6347
func (ctx *Context) WithContext(other context.Context) *Context {
64-
return newContext(ctx, ctx.e.Context(other), ctx.transaction)
48+
return newContext(ctx, ctx.engine.Context(other))
6549
}
6650

67-
// Engined structs provide an Engine
68-
type Engined interface {
69-
Engine() Engine
51+
var (
52+
contextSafetyOnce sync.Once
53+
contextSafetyDeniedFuncPCs []uintptr
54+
)
55+
56+
func contextSafetyCheck(e Engine) {
57+
if setting.IsProd && !setting.IsInTesting {
58+
return
59+
}
60+
if e == nil {
61+
return
62+
}
63+
// Only do this check for non-end-users. If the problem could be fixed in the future, this code could be removed.
64+
contextSafetyOnce.Do(func() {
65+
// try to figure out the bad functions to deny
66+
type m struct{}
67+
_ = e.SQL("SELECT 1").Iterate(&m{}, func(int, any) error {
68+
callers := make([]uintptr, 32)
69+
callerNum := runtime.Callers(1, callers)
70+
for i := 0; i < callerNum; i++ {
71+
if funcName := runtime.FuncForPC(callers[i]).Name(); funcName == "xorm.io/xorm.(*Session).Iterate" {
72+
contextSafetyDeniedFuncPCs = append(contextSafetyDeniedFuncPCs, callers[i])
73+
}
74+
}
75+
return nil
76+
})
77+
if len(contextSafetyDeniedFuncPCs) != 1 {
78+
panic(errors.New("unable to determine the functions to deny"))
79+
}
80+
})
81+
82+
// it should be very fast: xxxx ns/op
83+
callers := make([]uintptr, 32)
84+
callerNum := runtime.Callers(3, callers) // skip 3: runtime.Callers, contextSafetyCheck, GetEngine
85+
for i := 0; i < callerNum; i++ {
86+
if slices.Contains(contextSafetyDeniedFuncPCs, callers[i]) {
87+
panic(errors.New("using database context in an iterator would cause corrupted results"))
88+
}
89+
}
7090
}
7191

72-
// GetEngine will get a db Engine from this context or return an Engine restricted to this context
92+
// GetEngine gets an existing db Engine/Statement or creates a new Session
7393
func GetEngine(ctx context.Context) Engine {
74-
if e := getEngine(ctx); e != nil {
94+
if e := getExistingEngine(ctx); e != nil {
7595
return e
7696
}
7797
return x.Context(ctx)
7898
}
7999

80-
// getEngine will get a db Engine from this context or return nil
81-
func getEngine(ctx context.Context) Engine {
82-
if engined, ok := ctx.(Engined); ok {
83-
return engined.Engine()
100+
// getExistingEngine gets an existing db Engine/Statement from this context or returns nil
101+
func getExistingEngine(ctx context.Context) (e Engine) {
102+
defer func() { contextSafetyCheck(e) }()
103+
if engined, ok := ctx.(*Context); ok {
104+
return engined.engine
84105
}
85-
enginedInterface := ctx.Value(enginedContextKey)
86-
if enginedInterface != nil {
87-
return enginedInterface.(Engined).Engine()
106+
if engined, ok := ctx.Value(engineContextKey).(*Context); ok {
107+
return engined.engine
88108
}
89109
return nil
90110
}
@@ -132,23 +152,23 @@ func (c *halfCommitter) Close() error {
132152
// d. It doesn't mean rollback is forbidden, but always do it only when there is an error, and you do want to rollback.
133153
func TxContext(parentCtx context.Context) (*Context, Committer, error) {
134154
if sess, ok := inTransaction(parentCtx); ok {
135-
return newContext(parentCtx, sess, true), &halfCommitter{committer: sess}, nil
155+
return newContext(parentCtx, sess), &halfCommitter{committer: sess}, nil
136156
}
137157

138158
sess := x.NewSession()
139159
if err := sess.Begin(); err != nil {
140-
sess.Close()
160+
_ = sess.Close()
141161
return nil, nil, err
142162
}
143163

144-
return newContext(DefaultContext, sess, true), sess, nil
164+
return newContext(DefaultContext, sess), sess, nil
145165
}
146166

147167
// WithTx represents executing database operations on a transaction, if the transaction exist,
148168
// this function will reuse it otherwise will create a new one and close it when finished.
149169
func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
150170
if sess, ok := inTransaction(parentCtx); ok {
151-
err := f(newContext(parentCtx, sess, true))
171+
err := f(newContext(parentCtx, sess))
152172
if err != nil {
153173
// rollback immediately, in case the caller ignores returned error and tries to commit the transaction.
154174
_ = sess.Close()
@@ -165,7 +185,7 @@ func txWithNoCheck(parentCtx context.Context, f func(ctx context.Context) error)
165185
return err
166186
}
167187

168-
if err := f(newContext(parentCtx, sess, true)); err != nil {
188+
if err := f(newContext(parentCtx, sess)); err != nil {
169189
return err
170190
}
171191

@@ -312,7 +332,7 @@ func InTransaction(ctx context.Context) bool {
312332
}
313333

314334
func inTransaction(ctx context.Context) (*xorm.Session, bool) {
315-
e := getEngine(ctx)
335+
e := getExistingEngine(ctx)
316336
if e == nil {
317337
return nil, false
318338
}

models/db/context_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,47 @@ func TestTxContext(t *testing.T) {
8484
}))
8585
}
8686
}
87+
88+
func TestContextSafety(t *testing.T) {
89+
type TestModel1 struct {
90+
ID int64
91+
}
92+
type TestModel2 struct {
93+
ID int64
94+
}
95+
assert.NoError(t, unittest.GetXORMEngine().Sync(&TestModel1{}, &TestModel2{}))
96+
assert.NoError(t, db.TruncateBeans(db.DefaultContext, &TestModel1{}, &TestModel2{}))
97+
testCount := 10
98+
for i := 1; i <= testCount; i++ {
99+
assert.NoError(t, db.Insert(db.DefaultContext, &TestModel1{ID: int64(i)}))
100+
assert.NoError(t, db.Insert(db.DefaultContext, &TestModel2{ID: int64(-i)}))
101+
}
102+
103+
actualCount := 0
104+
// here: db.GetEngine(db.DefaultContext) is a new *Session created from *Engine
105+
_ = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
106+
_ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error {
107+
// here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false,
108+
// and the internal states (including "cond" and others) are always there and not be reset in this callback.
109+
m1 := bean.(*TestModel1)
110+
assert.EqualValues(t, i+1, m1.ID)
111+
112+
// here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ...
113+
// and it conflicts with the "Iterate"'s internal states.
114+
// has, err := db.GetEngine(ctx).Get(&TestModel2{ID: -m1.ID})
115+
116+
actualCount++
117+
return nil
118+
})
119+
return nil
120+
})
121+
assert.EqualValues(t, testCount, actualCount)
122+
123+
// deny the bad usages
124+
assert.PanicsWithError(t, "using database context in an iterator would cause corrupted results", func() {
125+
_ = unittest.GetXORMEngine().Iterate(&TestModel1{}, func(i int, bean any) error {
126+
_ = db.GetEngine(db.DefaultContext)
127+
return nil
128+
})
129+
})
130+
}

models/db/engine.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,7 @@ func InitEngine(ctx context.Context) error {
161161
// SetDefaultEngine sets the default engine for db
162162
func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) {
163163
x = eng
164-
DefaultContext = &Context{
165-
Context: ctx,
166-
e: x,
167-
}
164+
DefaultContext = &Context{Context: ctx, engine: x}
168165
}
169166

170167
// UnsetDefaultEngine closes and unsets the default engine

0 commit comments

Comments
 (0)