mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-02-17 21:47:02 +02:00
fix: issues and pulls route permitted extra characters (#10185)
Fix a issue where the `/{owner}/{repo}/issues` and `/{owner}/{repo}/pulls` routes permitted the addition of extra characters in the URL.
Resolves forgejo/forgejo#9954.
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10185
Reviewed-by: Lucas <sclu1034@noreply.codeberg.org>
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Adora <me@adora.codes>
Co-committed-by: Adora <me@adora.codes>
This commit is contained in:
@@ -21,7 +21,7 @@ func TestRoute1(t *testing.T) {
|
||||
recorder.Body = buff
|
||||
|
||||
r := NewRoute()
|
||||
r.Get("/{username}/{reponame}/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
r.Get("/{username}/{reponame}/{type:^(issues|pulls)$}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
username := chi.URLParam(req, "username")
|
||||
assert.Equal(t, "gitea", username)
|
||||
reponame := chi.URLParam(req, "reponame")
|
||||
@@ -46,7 +46,7 @@ func TestRoute2(t *testing.T) {
|
||||
r := NewRoute()
|
||||
r.Group("/{username}/{reponame}", func() {
|
||||
r.Group("", func() {
|
||||
r.Get("/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
r.Get("/{type:^(issues|pulls)$}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
username := chi.URLParam(req, "username")
|
||||
assert.Equal(t, "gitea", username)
|
||||
reponame := chi.URLParam(req, "reponame")
|
||||
@@ -56,7 +56,7 @@ func TestRoute2(t *testing.T) {
|
||||
hit = 0
|
||||
})
|
||||
|
||||
r.Get("/{type:issues|pulls}/{index}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
r.Get("/{type:^(issues|pulls)$}/{index}", func(resp http.ResponseWriter, req *http.Request) {
|
||||
username := chi.URLParam(req, "username")
|
||||
assert.Equal(t, "gitea", username)
|
||||
reponame := chi.URLParam(req, "reponame")
|
||||
|
||||
@@ -1191,7 +1191,7 @@ func registerRoutes(m *web.Route) {
|
||||
m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists).
|
||||
Get(repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff).
|
||||
Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, web.Bind(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost)
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
m.Group("/{type:^(issues|pulls)$}", func() {
|
||||
m.Group("/{index}", func() {
|
||||
m.Get("/info", repo.GetIssueInfo)
|
||||
m.Get("/summary-card", repo.DrawIssueSummaryCard)
|
||||
@@ -1216,7 +1216,7 @@ func registerRoutes(m *web.Route) {
|
||||
}, context.RepoMustNotBeArchived(), reqRepoIssueReader)
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/{type:issues|pulls}", func() {
|
||||
m.Group("/{type:^(issues|pulls)$}", func() {
|
||||
m.Group("/{index}", func() {
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
m.Post("/action-user-trust", reqRepoActionsReader, actions.MustEnableActions, reqRepoDelegateActionTrust, repo.UpdateTrustWithPullRequestActions)
|
||||
@@ -1379,9 +1379,9 @@ func registerRoutes(m *web.Route) {
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/issues/posters", repo.IssuePosters) // it can't use {type:issues|pulls} because other routes like "/pulls/{index}" has higher priority
|
||||
m.Get("/{type:issues|pulls}", repo.Issues)
|
||||
m.Get("/{type:issues|pulls}/{index}", repo.ViewIssue)
|
||||
m.Group("/{type:issues|pulls}/{index}/content-history", func() {
|
||||
m.Get("/{type:^(issues|pulls)$}", repo.Issues)
|
||||
m.Get("/{type:^(issues|pulls)$}/{index}", repo.ViewIssue)
|
||||
m.Group("/{type:^(issues|pulls)$}/{index}/content-history", func() {
|
||||
m.Get("/overview", repo.GetContentHistoryOverview)
|
||||
m.Get("/list", repo.GetContentHistoryList)
|
||||
m.Get("/detail", repo.GetContentHistoryDetail)
|
||||
|
||||
@@ -1591,3 +1591,43 @@ func TestIssueAndPullRedirect(t *testing.T) {
|
||||
req = NewRequest(t, "GET", "/user2/repo1/pulls/9999999")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
}
|
||||
|
||||
func TestIssueUrlHandling(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
t.Run("Overview correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "user2/repo1/issues")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Issue correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "user2/repo1/issues/1")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Overview left-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/extra_text_issues")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Overview right-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/issues_extra_text")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Issue left-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/extra_text_issues/5")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Issue right-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/issues_extra_text/5")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -171,3 +171,73 @@ func TestShowMergeForManualMerge(t *testing.T) {
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
htmlDoc.AssertElement(t, "#pull-request-merge-form", true)
|
||||
}
|
||||
|
||||
func TestPullUrlHandling(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
t.Run("Overview correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/pulls")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Pull correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/pulls/5")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Overview left-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/extra_text_pulls")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Overview right-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/pulls_extra_text")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Pull left-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/extra_text_pulls/5")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Pull right-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/pulls_extra_text/5")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("POST Title correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
session := loginUser(t, "user2")
|
||||
|
||||
req := NewRequestWithValues(t, "POST", "/user2/repo1/issues/5/title", map[string]string{"title": "test"})
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("POST Title padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
session := loginUser(t, "user2")
|
||||
|
||||
req := NewRequestWithValues(t, "POST", "/user2/repo1/issues_extra_text/5/title", map[string]string{"title": "test"})
|
||||
session.MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("Pull content overview correct", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/pulls/5/content-history/overview")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Pull content overview left-padded", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequest(t, "GET", "/user2/repo1/extra_text_pulls/5/content-history/overview")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user