loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: use correct input for strip slashes middleware (#7295)

- The router must use the escaped path in order to ensure correct functionality (at least, that is what they say). However `req.URL.Path` shouldn't be set to the escaped path, which is fixed in this patch.
- Simplify the logic and no longer try to use `rctx.RoutePath`, this is only useful if the middleware was placed after some routing parsing was done.
- Resolves forgejo/forgejo#7294
- Resolves forgejo/forgejo#7292
- Add unit test

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7295
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>

authored by

Gusted
Gusted
and committed by
Earl Warren
cff284fd 2d54cbc8

+35 -23
+15 -15
routers/common/middleware.go
··· 77 77 78 78 func stripSlashesMiddleware(next http.Handler) http.Handler { 79 79 return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { 80 - // First of all escape the URL RawPath to ensure that all routing is done using a correctly escaped URL 80 + // Ensure that URL.RawPath is always set. 81 81 req.URL.RawPath = req.URL.EscapedPath() 82 82 83 - urlPath := req.URL.RawPath 84 - rctx := chi.RouteContext(req.Context()) 85 - if rctx != nil && rctx.RoutePath != "" { 86 - urlPath = rctx.RoutePath 87 - } 88 - 89 - sanitizedPath := &strings.Builder{} 90 - prevWasSlash := false 91 - for _, chr := range strings.TrimRight(urlPath, "/") { 92 - if chr != '/' || !prevWasSlash { 93 - sanitizedPath.WriteRune(chr) 83 + sanitize := func(path string) string { 84 + sanitizedPath := &strings.Builder{} 85 + prevWasSlash := false 86 + for _, chr := range strings.TrimRight(path, "/") { 87 + if chr != '/' || !prevWasSlash { 88 + sanitizedPath.WriteRune(chr) 89 + } 90 + prevWasSlash = chr == '/' 94 91 } 95 - prevWasSlash = chr == '/' 92 + return sanitizedPath.String() 96 93 } 97 94 98 - req.URL.Path = sanitizedPath.String() 95 + // Sanitize the unescaped path for application logic. 96 + req.URL.Path = sanitize(req.URL.Path) 97 + rctx := chi.RouteContext(req.Context()) 99 98 if rctx != nil { 100 - rctx.RoutePath = req.URL.Path 99 + // Sanitize the escaped path for routing. 100 + rctx.RoutePath = sanitize(req.URL.RawPath) 101 101 } 102 102 next.ServeHTTP(resp, req) 103 103 })
+19 -7
routers/common/middleware_test.go
··· 15 15 16 16 func TestStripSlashesMiddleware(t *testing.T) { 17 17 type test struct { 18 - name string 19 - expectedPath string 20 - inputPath string 18 + name string 19 + expectedPath string 20 + expectedNormalPath string 21 + inputPath string 21 22 } 22 23 23 24 tests := []test{ ··· 57 58 expectedPath: "/repo/migrate", 58 59 }, 59 60 { 60 - name: "path with encoded slash", 61 - inputPath: "/user2/%2F%2Frepo1", 62 - expectedPath: "/user2/%2F%2Frepo1", 61 + name: "path with encoded slash", 62 + inputPath: "/user2/%2F%2Frepo1", 63 + expectedPath: "/user2/%2F%2Frepo1", 64 + expectedNormalPath: "/user2/repo1", 65 + }, 66 + { 67 + name: "path with space", 68 + inputPath: "/assets/css/theme%20cappuccino.css", 69 + expectedPath: "/assets/css/theme%20cappuccino.css", 70 + expectedNormalPath: "/assets/css/theme cappuccino.css", 63 71 }, 64 72 } 65 73 ··· 69 77 70 78 called := false 71 79 r.Get("*", func(w http.ResponseWriter, r *http.Request) { 72 - assert.Equal(t, tt.expectedPath, r.URL.Path) 80 + if tt.expectedNormalPath != "" { 81 + assert.Equal(t, tt.expectedNormalPath, r.URL.Path) 82 + } else { 83 + assert.Equal(t, tt.expectedPath, r.URL.Path) 84 + } 73 85 74 86 rctx := chi.RouteContext(r.Context()) 75 87 assert.Equal(t, tt.expectedPath, rctx.RoutePath)
+1 -1
services/context/repo.go
··· 1058 1058 1059 1059 if refType == RepoRefLegacy { 1060 1060 // redirect from old URL scheme to new URL scheme 1061 - prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.PathParamRaw("*"))), strings.ToLower(ctx.Repo.RepoLink)) 1061 + prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*"))), strings.ToLower(ctx.Repo.RepoLink)) 1062 1062 1063 1063 ctx.Redirect(path.Join( 1064 1064 ctx.Repo.RepoLink,