Skip to content

Commit 40e99e7

Browse files
authored
Merge branch 'go-gitea:main' into patch2
2 parents 4957eb9 + e0745eb commit 40e99e7

File tree

206 files changed

+2632
-2522
lines changed

Some content is hidden

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

206 files changed

+2632
-2522
lines changed

.eslintrc.cjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ module.exports = {
9191
plugins: ['@vitest/eslint-plugin'],
9292
globals: vitestPlugin.environments.env.globals,
9393
rules: {
94+
'github/unescaped-html-literal': [0],
9495
'@vitest/consistent-test-filename': [0],
9596
'@vitest/consistent-test-it': [0],
9697
'@vitest/expect-expect': [0],
@@ -423,7 +424,7 @@ module.exports = {
423424
'github/no-useless-passive': [2],
424425
'github/prefer-observers': [2],
425426
'github/require-passive-events': [2],
426-
'github/unescaped-html-literal': [0],
427+
'github/unescaped-html-literal': [2],
427428
'grouped-accessor-pairs': [2],
428429
'guard-for-in': [0],
429430
'id-blacklist': [0],

SECURITY.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ Please **DO NOT** file a public issue, instead send your report privately to `se
1414

1515
Due to the sensitive nature of security information, you can use the below GPG public key to encrypt your mail body.
1616

17-
The PGP key is valid until July 9, 2025.
17+
The PGP key is valid until July 4, 2026.
1818

1919
```
2020
Key ID: 6FCD2D5B
2121
Key Type: RSA
22-
Expires: 7/9/2025
22+
Expires: 7/4/2026
2323
Key Size: 4096/4096
2424
Fingerprint: 3DE0 3D1E 144A 7F06 9359 99DC AAFD 2381 6FCD 2D5B
2525
```
@@ -42,18 +42,18 @@ lzpAjnN9/KLtQroutrm+Ft0mdjDiJUeFVl1cOHDhoyfCsQh62HumoyZoZvqzQd6e
4242
AbN11nq6aViMe2Q3je1AbiBnRnQSHxt1Tc8X4IshO3MQK1Sk7oPI6LA5oQARAQAB
4343
tCJHaXRlYSBTZWN1cml0eSA8c2VjdXJpdHlAZ2l0ZWEuaW8+iQJXBBMBCABBAhsD
4444
BQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEEPeA9HhRKfwaTWZncqv0jgW/N
45-
LVsFAmaMse0FCQW4fW8ACgkQqv0jgW/NLVtXLg/+PF4G9Jhlui15BTNlEBJAV2P/
46-
1QlAV2krk0fP7tykn0FR9RfGIfVV/kwC1f+ouosYPQDDevl9LWdUIM+g94DtNo2o
47-
7ACpcL3morvt5lVGpIZHL8TbX0qmFRXL/pB/cB+K6IwYvh2mrbp2zH+r4SCRyFYq
48-
BjgXYFTI1MylJ1ShAjU6Z+m3oJ+2xs5LzHS0X6zkTjzA2Zl4zQzciQ9T+wJcE7Zi
49-
HXdM1+YMF8KGNP8J9Rpug5oNDJ98lgZirRY7c3A/1xmYBiPnULwuuymdqEZO7l70
50-
SeAlE1RWYX8kbOBnBb/KY4XwE3Vic1oEzc9DiPWVH1ElX86WNNsFzuyULiwoBoWg
51-
pqZGhL9x1p5+46RGQSDczsHM7YGVtfYOiDo2PAVrmwsT0BnXnK8Oe3YIkvmUPEJu
52-
OkLt0Z6A5n8pz8zhQzuApwBsK4ncJ8zTCpvz/pfKKqZC/Vnoh3gKGhDGvOZ+b5IJ
53-
0kUTe2JsbnwFixDUMDtacQ1op8XOyLoLVmgqLn0+Pws4XPBlMof2bioFir3yHKnP
54-
gNchsF1agrlSIo5GA8u4ga+IlCSfvFIKrl7+cxacKcJYt/vbOU5KcvVJI5EtHKCG
55-
xfHjHY2ah1Qww7SxW6IXiRZZzPpsL2mBM2CD7N3qh9bV2s27wxYCdUodsIZbiyHe
56-
oWPzfBnkmiAN8KlZxHm5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
45+
LVsFAmhoHmkFCQeT6esACgkQqv0jgW/NLVuFLRAAmjBQSKRAgs2bFIEj7HLAbDp4
46+
f+XkdH+GsT3jRPOZ9QZgmtM+TfoE4yNgIVfOl+s4RdjM/W4QzqZuPQ55hbEHd056
47+
cJmm7B+6GsHFcdrPmh65sOCEIyh4+t45dUfeWpFsDPqm9j1UHXAJQIpB8vDEVAPH
48+
t+3wLCk8GMPJs1o5tIyMmaO23ngvkwn8eG7KgY+rp2PzObrb5g7ppci0ILzILkrp
49+
HVjZsEfUWRgSVF7LuU5ppqDKrlcqwUpQq6n3kGMZcLrCp6ACKP04TBmTfUxNwdL7
50+
I0N7apI2Pbct9T1Gv/lYAUFWyU2c3gh/EBLbO6BukaLOFRQHrtNfdJV/YnMPlcXr
51+
LUJjK9K4eAH9DsrZqrisz/LthsC2BaNIN3KRMTk5YTYgmIh8GXzSgihORmtDFELC
52+
RroID3pTuS0zjXh+wpY9GuPTh7UW23p42Daxca4fAT4k5EclvDRUrL21xMopPMiL
53+
HuNdELz4FVchRTy05PjzKVyjVInDNojE2KUxnjxZDzYJ6aT/g+coD5yfntYm8BEj
54+
+ZzL0ndZES54hzKLpv7zwBQwFzam68clZYmDPILOPTflQDfpGEWmJK4undFU5obz
55+
ZsQRz0R3ulspChATbZxO0d5LX2obLpKO9X3b5VoO1KF+R8Vjw1Y0KxrNZ6rIcfqH
56+
Z50QVQKSe9dm08K0ON+5Ag0EYrVn/gEQALrFLQjCR3GjuHSindz0rd3Fnx/t7Sen
5757
T+p07yCSSoSlmnJHCQmwh4vfg1blyz0zZ4vkIhtpHsEgc+ZAG+WQXSsJ2iRz+eSN
5858
GwoOQl4XC3n+QWkc1ws+btr48+6UqXIQU+F8TPQyx/PIgi2nZXJB7f5+mjCqsk46
5959
XvH4nTr4kJjuqMSR/++wvre2qNQRa/q/dTsK0OaN/mJsdX6Oi+aGNaQJUhIG7F+E
@@ -65,19 +65,19 @@ s+GsP9I3cmWWQcKYxWHtE8xTXnNCVPFZQj2nwhJzae8ypfOtulBRA3dUKWGKuDH/
6565
axFENhUsT397aOU3qkP/od4a64JyNIEo4CTTSPVeWd7njsGqli2U3A4xL2CcyYvt
6666
D/MWcMBGEoLSNTswwKdom4FaJpn5KThnK/T0bQcmJblJhoCtppXisbexZnCpuS0x
6767
Zdlm2T14KJ3LABEBAAGJAjwEGAEIACYCGwwWIQQ94D0eFEp/BpNZmdyq/SOBb80t
68-
WwUCZoyyjQUJBbh+DwAKCRCq/SOBb80tW18XD/9MXztmf01MT+1kZdBouZ/7Rp/7
69-
9kuqo//B1G+RXau4oFtPqb67kNe2WaIc3u5B73PUHsMf3i6z4ib2KbMhZZerLn0O
70-
dRglcuPeNWmsASY3dH/XVG0cT0zvvWegagd12TJEl3Vs+7XNrOw4cwDj9L1+GH9m
71-
kSt4uaANWn/6a3RvMRhiVEYuNwhAzcKaactPmYqrLJgoVLbRSDkgyHaMQ2jKgLxk
72-
ifS/fvluGV0ub2Po6DJiqfRpd1tDvPhe9y1+r1WFDZsOcvTcZUfSt/7dXMGfqGu0
73-
2daVFlfeSXSALrDE5uc0UxodHCpP3sqRYDZevGLBRaaTkIjYXG/+N898+7K5WJF4
74-
xXOLWxM2cwGkG7eC9pugcDnBp9XlF7O+GBiZ05JUe5flXDQFZ+h3exjopu6KHF1B
75-
RnzNy8LC0UKb+AuvRIOLV92a9Q9wGWU/jaVDu6nZ0umAeuSzxiHoDsonm0Fl9QAz
76-
2/xCokebuoeLrEK7R2af3X86mqq3sVO4ax+HPYChzOaVQBiHUW/TAldWcldYYphR
77-
/e2WsbmQfvCRtz/bZfo+aUVnrHNjzVMtF2SszdVmA/04Y8pS28MqtuRqhm5DPOOd
78-
g1YeUywK5jRZ1twyo1kzJEFPLaoeaXaycsR1PMVBW0Urik5mrR/pOWq7PPoZoKb2
79-
lXYLE8bwkuQTmsyL1g==
80-
=9i7d
68+
WwUCaGgeJAUJB5PppgAKCRCq/SOBb80tW/NWEACB6Jrf0gWlk7e+hNCdnbM0ZVWU
69+
f2sHNFfXxxsdhpcDgKbNHtkZb8nZgv8AX+5fTtUwMVa3vKcdw30xFiIM5N7cCIPV
70+
vg/5z5BtfEaitnabEUG2iiVDIy8IHXIcK10rX+7BosA3QDl2PsiBHwyi5G13lRk8
71+
zGTSNDuOalug33h5/lr2dPigamkq74Aoy29q8Rjad6GfWHipL2bFimgtY+Zdi0BH
72+
NLk4EJXxj1SgVx5dtkQzWJReBA5M+FQ4QYQZBO+f4TDoOLmjui152uhkoLBQbGAa
73+
WWJFTVxm0bG5MXloEL3gA8DfU7XDwuW/sHJC5pBko8RpQViooOhckMepZV3Y83DK
74+
bwLYa3JmPgj2rEv4993dvrJbQhpGd082HOxOsllCs8pgNq1SnXpWYfcGTgGKC3ts
75+
U8YZUUJUQ7mi2L8Tv3ix20c9EiGmA30JAmA8eZTC3cWup91ZkkVBFRml2czTXajd
76+
RWZ6GbHV5503ueDQcB8yBVgF3CSixs67+dGSbD3p86OqGrjAcJzM5TFbNKcnGLdE
77+
kGbZpNwAISy750lXzXKmyrh5RTCeTOQerbwCMBvHZO+HAevA/LXDTw2OAiSIQlP5
78+
sYA4sFYLQ30OAkgJcmdp/pSgVj/erNtSN07ClrOpDb/uFpQymO6K2h0Pst3feNVK
79+
9M2VbqL9C51z/wyHLg==
80+
=SfZA
8181
-----END PGP PUBLIC KEY BLOCK-----
8282
8383
```

models/issues/comment.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ func (c *Comment) LoadReactions(ctx context.Context, repo *repo_model.Repository
715715
return nil
716716
}
717717

718-
func (c *Comment) loadReview(ctx context.Context) (err error) {
718+
// LoadReview loads the associated review
719+
func (c *Comment) LoadReview(ctx context.Context) (err error) {
719720
if c.ReviewID == 0 {
720721
return nil
721722
}
@@ -732,11 +733,6 @@ func (c *Comment) loadReview(ctx context.Context) (err error) {
732733
return nil
733734
}
734735

735-
// LoadReview loads the associated review
736-
func (c *Comment) LoadReview(ctx context.Context) error {
737-
return c.loadReview(ctx)
738-
}
739-
740736
// DiffSide returns "previous" if Comment.Line is a LOC of the previous changes and "proposed" if it is a LOC of the proposed changes.
741737
func (c *Comment) DiffSide() string {
742738
if c.Line < 0 {
@@ -856,7 +852,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
856852
}
857853
if comment.ReviewID != 0 {
858854
if comment.Review == nil {
859-
if err := comment.loadReview(ctx); err != nil {
855+
if err := comment.LoadReview(ctx); err != nil {
860856
return err
861857
}
862858
}

modules/auth/httpauth/httpauth.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package httpauth
5+
6+
import (
7+
"encoding/base64"
8+
"strings"
9+
10+
"code.gitea.io/gitea/modules/util"
11+
)
12+
13+
type BasicAuth struct {
14+
Username, Password string
15+
}
16+
17+
type BearerToken struct {
18+
Token string
19+
}
20+
21+
type ParsedAuthorizationHeader struct {
22+
BasicAuth *BasicAuth
23+
BearerToken *BearerToken
24+
}
25+
26+
func ParseAuthorizationHeader(header string) (ret ParsedAuthorizationHeader, _ bool) {
27+
parts := strings.Fields(header)
28+
if len(parts) != 2 {
29+
return ret, false
30+
}
31+
if util.AsciiEqualFold(parts[0], "basic") {
32+
s, err := base64.StdEncoding.DecodeString(parts[1])
33+
if err != nil {
34+
return ret, false
35+
}
36+
u, p, ok := strings.Cut(string(s), ":")
37+
if !ok {
38+
return ret, false
39+
}
40+
ret.BasicAuth = &BasicAuth{Username: u, Password: p}
41+
return ret, true
42+
} else if util.AsciiEqualFold(parts[0], "token") || util.AsciiEqualFold(parts[0], "bearer") {
43+
ret.BearerToken = &BearerToken{Token: parts[1]}
44+
return ret, true
45+
}
46+
return ret, false
47+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package httpauth
5+
6+
import (
7+
"encoding/base64"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestParseAuthorizationHeader(t *testing.T) {
14+
type parsed = ParsedAuthorizationHeader
15+
type basic = BasicAuth
16+
type bearer = BearerToken
17+
cases := []struct {
18+
headerValue string
19+
expected parsed
20+
ok bool
21+
}{
22+
{"", parsed{}, false},
23+
{"?", parsed{}, false},
24+
{"foo", parsed{}, false},
25+
{"any value", parsed{}, false},
26+
27+
{"Basic ?", parsed{}, false},
28+
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo")), parsed{}, false},
29+
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
30+
{"basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
31+
32+
{"token value", parsed{BearerToken: &bearer{"value"}}, true},
33+
{"Token value", parsed{BearerToken: &bearer{"value"}}, true},
34+
{"bearer value", parsed{BearerToken: &bearer{"value"}}, true},
35+
{"Bearer value", parsed{BearerToken: &bearer{"value"}}, true},
36+
{"Bearer wrong value", parsed{}, false},
37+
}
38+
for _, c := range cases {
39+
ret, ok := ParseAuthorizationHeader(c.headerValue)
40+
assert.Equal(t, c.ok, ok, "header %q", c.headerValue)
41+
assert.Equal(t, c.expected, ret, "header %q", c.headerValue)
42+
}
43+
}

modules/base/tool.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ import (
88
"crypto/sha1"
99
"crypto/sha256"
1010
"crypto/subtle"
11-
"encoding/base64"
1211
"encoding/hex"
13-
"errors"
1412
"fmt"
1513
"hash"
1614
"strconv"
17-
"strings"
1815
"time"
1916

2017
"code.gitea.io/gitea/modules/setting"
@@ -36,19 +33,6 @@ func ShortSha(sha1 string) string {
3633
return util.TruncateRunes(sha1, 10)
3734
}
3835

39-
// BasicAuthDecode decode basic auth string
40-
func BasicAuthDecode(encoded string) (string, string, error) {
41-
s, err := base64.StdEncoding.DecodeString(encoded)
42-
if err != nil {
43-
return "", "", err
44-
}
45-
46-
if username, password, ok := strings.Cut(string(s), ":"); ok {
47-
return username, password, nil
48-
}
49-
return "", "", errors.New("invalid basic authentication")
50-
}
51-
5236
// VerifyTimeLimitCode verify time limit code
5337
func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
5438
if len(code) <= 18 {

modules/base/tool_test.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,6 @@ func TestShortSha(t *testing.T) {
2626
assert.Equal(t, "veryverylo", ShortSha("veryverylong"))
2727
}
2828

29-
func TestBasicAuthDecode(t *testing.T) {
30-
_, _, err := BasicAuthDecode("?")
31-
assert.Equal(t, "illegal base64 data at input byte 0", err.Error())
32-
33-
user, pass, err := BasicAuthDecode("Zm9vOmJhcg==")
34-
assert.NoError(t, err)
35-
assert.Equal(t, "foo", user)
36-
assert.Equal(t, "bar", pass)
37-
38-
_, _, err = BasicAuthDecode("aW52YWxpZA==")
39-
assert.Error(t, err)
40-
41-
_, _, err = BasicAuthDecode("invalid")
42-
assert.Error(t, err)
43-
44-
_, _, err = BasicAuthDecode("YWxpY2U=") // "alice", no colon
45-
assert.Error(t, err)
46-
}
47-
4829
func TestVerifyTimeLimitCode(t *testing.T) {
4930
defer test.MockVariableValue(&setting.InstallLock, true)()
5031
initGeneralSecret := func(secret string) {

modules/fileicon/entry.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ package fileicon
66
import "code.gitea.io/gitea/modules/git"
77

88
type EntryInfo struct {
9-
FullName string
9+
BaseName string
1010
EntryMode git.EntryMode
1111
SymlinkToMode git.EntryMode
1212
IsOpen bool
1313
}
1414

15-
func EntryInfoFromGitTreeEntry(gitEntry *git.TreeEntry) *EntryInfo {
16-
ret := &EntryInfo{FullName: gitEntry.Name(), EntryMode: gitEntry.Mode()}
15+
func EntryInfoFromGitTreeEntry(commit *git.Commit, fullPath string, gitEntry *git.TreeEntry) *EntryInfo {
16+
ret := &EntryInfo{BaseName: gitEntry.Name(), EntryMode: gitEntry.Mode()}
1717
if gitEntry.IsLink() {
18-
if te, err := gitEntry.FollowLink(); err == nil && te.IsDir() {
19-
ret.SymlinkToMode = te.Mode()
18+
if res, err := git.EntryFollowLink(commit, fullPath, gitEntry); err == nil && res.TargetEntry.IsDir() {
19+
ret.SymlinkToMode = res.TargetEntry.Mode()
2020
}
2121
}
2222
return ret

modules/fileicon/material.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package fileicon
55

66
import (
77
"html/template"
8-
"path"
98
"strings"
109
"sync"
1110

@@ -134,7 +133,7 @@ func (m *MaterialIconProvider) FindIconName(entry *EntryInfo) string {
134133
return "folder-git"
135134
}
136135

137-
fileNameLower := strings.ToLower(path.Base(entry.FullName))
136+
fileNameLower := strings.ToLower(entry.BaseName)
138137
if entry.EntryMode.IsDir() {
139138
if s, ok := m.rules.FolderNames[fileNameLower]; ok {
140139
return s

modules/fileicon/material_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ func TestMain(m *testing.M) {
2020
func TestFindIconName(t *testing.T) {
2121
unittest.PrepareTestEnv(t)
2222
p := fileicon.DefaultMaterialIconProvider()
23-
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.php", EntryMode: git.EntryModeBlob}))
24-
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.PHP", EntryMode: git.EntryModeBlob}))
25-
assert.Equal(t, "javascript", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.js", EntryMode: git.EntryModeBlob}))
26-
assert.Equal(t, "visualstudio", p.FindIconName(&fileicon.EntryInfo{FullName: "foo.vba", EntryMode: git.EntryModeBlob}))
23+
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.php", EntryMode: git.EntryModeBlob}))
24+
assert.Equal(t, "php", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.PHP", EntryMode: git.EntryModeBlob}))
25+
assert.Equal(t, "javascript", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.js", EntryMode: git.EntryModeBlob}))
26+
assert.Equal(t, "visualstudio", p.FindIconName(&fileicon.EntryInfo{BaseName: "foo.vba", EntryMode: git.EntryModeBlob}))
2727
}

0 commit comments

Comments
 (0)