diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 496bec0e24..79793ad47f 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2407,8 +2407,8 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The first locale will be used as the default if user browser's language doesn't match any locale in the list. -;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,nds,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg,it-IT,fi-FI,fil,eo,tr-TR,cs-CZ,sl,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID -;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Plattdüütsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Filipino,Esperanto,Türkçe,Čeština,Slovenščina,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia +;LANGS = en-US,zh-CN,zh-HK,zh-TW,da,de-DE,nds,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg,it-IT,fi-FI,fil,eo,tr-TR,cs-CZ,sl,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID +;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Danish,Deutsch,Plattdüütsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Filipino,Esperanto,Türkçe,Čeština,Slovenščina,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/go.mod b/go.mod index 03b95cf748..278ee05733 100644 --- a/go.mod +++ b/go.mod @@ -47,13 +47,13 @@ require ( github.com/go-git/go-git/v5 v5.13.2 github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-openapi/spec v0.20.14 - github.com/go-sql-driver/mysql v1.8.1 + github.com/go-sql-driver/mysql v1.9.1 github.com/go-testfixtures/testfixtures/v3 v3.14.0 github.com/go-webauthn/webauthn v0.12.2 github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/golang-jwt/jwt/v5 v5.2.2 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/google/go-github/v64 v64.0.0 github.com/google/pprof v0.0.0-20241017200806-017d972448fc diff --git a/go.sum b/go.sum index 657b80d4a7..0997cdb85d 100644 --- a/go.sum +++ b/go.sum @@ -960,8 +960,8 @@ github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI= +github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= @@ -985,8 +985,8 @@ github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JP github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU= github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= diff --git a/modules/setting/i18n.go b/modules/setting/i18n.go index f4bacea218..c2e5822cf0 100644 --- a/modules/setting/i18n.go +++ b/modules/setting/i18n.go @@ -9,6 +9,7 @@ var defaultI18nLangNames = []string{ "zh-CN", "简体中文", "zh-HK", "繁體中文(香港)", "zh-TW", "繁體中文(台灣)", + "da", "Danish", "de-DE", "Deutsch", "nds", "Plattdüütsch", "fr-FR", "Français", diff --git a/routers/common/middleware.go b/routers/common/middleware.go index 8d136ef2c7..ee2e504ff1 100644 --- a/routers/common/middleware.go +++ b/routers/common/middleware.go @@ -77,27 +77,27 @@ func ProtocolMiddlewares() (handlers []any) { func stripSlashesMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - // First of all escape the URL RawPath to ensure that all routing is done using a correctly escaped URL + // Ensure that URL.RawPath is always set. req.URL.RawPath = req.URL.EscapedPath() - urlPath := req.URL.RawPath - rctx := chi.RouteContext(req.Context()) - if rctx != nil && rctx.RoutePath != "" { - urlPath = rctx.RoutePath - } - - sanitizedPath := &strings.Builder{} - prevWasSlash := false - for _, chr := range strings.TrimRight(urlPath, "/") { - if chr != '/' || !prevWasSlash { - sanitizedPath.WriteRune(chr) + sanitize := func(path string) string { + sanitizedPath := &strings.Builder{} + prevWasSlash := false + for _, chr := range strings.TrimRight(path, "/") { + if chr != '/' || !prevWasSlash { + sanitizedPath.WriteRune(chr) + } + prevWasSlash = chr == '/' } - prevWasSlash = chr == '/' + return sanitizedPath.String() } - req.URL.Path = sanitizedPath.String() + // Sanitize the unescaped path for application logic. + req.URL.Path = sanitize(req.URL.Path) + rctx := chi.RouteContext(req.Context()) if rctx != nil { - rctx.RoutePath = req.URL.Path + // Sanitize the escaped path for routing. + rctx.RoutePath = sanitize(req.URL.RawPath) } next.ServeHTTP(resp, req) }) diff --git a/routers/common/middleware_test.go b/routers/common/middleware_test.go index 0e111e1261..6126e0afcc 100644 --- a/routers/common/middleware_test.go +++ b/routers/common/middleware_test.go @@ -15,9 +15,10 @@ import ( func TestStripSlashesMiddleware(t *testing.T) { type test struct { - name string - expectedPath string - inputPath string + name string + expectedPath string + expectedNormalPath string + inputPath string } tests := []test{ @@ -57,9 +58,16 @@ func TestStripSlashesMiddleware(t *testing.T) { expectedPath: "/repo/migrate", }, { - name: "path with encoded slash", - inputPath: "/user2/%2F%2Frepo1", - expectedPath: "/user2/%2F%2Frepo1", + name: "path with encoded slash", + inputPath: "/user2/%2F%2Frepo1", + expectedPath: "/user2/%2F%2Frepo1", + expectedNormalPath: "/user2/repo1", + }, + { + name: "path with space", + inputPath: "/assets/css/theme%20cappuccino.css", + expectedPath: "/assets/css/theme%20cappuccino.css", + expectedNormalPath: "/assets/css/theme cappuccino.css", }, } @@ -69,7 +77,11 @@ func TestStripSlashesMiddleware(t *testing.T) { called := false r.Get("*", func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, tt.expectedPath, r.URL.Path) + if tt.expectedNormalPath != "" { + assert.Equal(t, tt.expectedNormalPath, r.URL.Path) + } else { + assert.Equal(t, tt.expectedPath, r.URL.Path) + } rctx := chi.RouteContext(r.Context()) assert.Equal(t, tt.expectedPath, rctx.RoutePath) diff --git a/services/context/repo.go b/services/context/repo.go index 8b8359fb70..ff03844c03 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -1058,7 +1058,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context if refType == RepoRefLegacy { // redirect from old URL scheme to new URL scheme - prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.PathParamRaw("*"))), strings.ToLower(ctx.Repo.RepoLink)) + prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*"))), strings.ToLower(ctx.Repo.RepoLink)) ctx.Redirect(path.Join( ctx.Repo.RepoLink,