[GITEA] Add repo empty check for branch feed

- If you attempted to get a branch feed on a empty repository, it would
result in a panic as the code expects that the branch exists.
- `context.RepoRefByType` would normally already 404 if the branch
doesn't exist, however if a repository is empty, it would not do this
check.
- Fix bug where `/atom/branch/*` would return a RSS feed.

(cherry picked from commit d27bcd98a41b69e313535e5e91e4272136a4bab1)
(cherry picked from commit c58566403df728c1f71b1dd554a573c011a59d7e)
(cherry picked from commit b8b3f6ab8b)
This commit is contained in:
Gusted 2023-10-20 11:40:32 +02:00 committed by Earl Warren
parent 57b4d775e1
commit 195520100b
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
4 changed files with 73 additions and 14 deletions

View file

@ -8,11 +8,12 @@ import (
) )
// RenderBranchFeed render format for branch or file // RenderBranchFeed render format for branch or file
func RenderBranchFeed(ctx *context.Context) { func RenderBranchFeed(feedType string) func(ctx *context.Context) {
_, _, showFeedType := GetFeedType(ctx.Params(":reponame"), ctx.Req) return func(ctx *context.Context) {
if ctx.Repo.TreePath == "" { if ctx.Repo.TreePath == "" {
ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) ShowBranchFeed(ctx, ctx.Repo.Repository, feedType)
} else { } else {
ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) ShowFileFeed(ctx, ctx.Repo.Repository, feedType)
}
} }
} }

View file

@ -731,12 +731,19 @@ func Home(ctx *context.Context) {
if setting.Other.EnableFeed { if setting.Other.EnableFeed {
isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req) isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req)
if isFeed { if isFeed {
switch { if ctx.Link == fmt.Sprintf("%s.%s", ctx.Repo.RepoLink, showFeedType) {
case ctx.Link == fmt.Sprintf("%s.%s", ctx.Repo.RepoLink, showFeedType):
feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType)
case ctx.Repo.TreePath == "": return
}
if ctx.Repo.Repository.IsEmpty {
ctx.NotFound("MustBeNotEmpty", nil)
return
}
if ctx.Repo.TreePath == "" {
feed.ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) feed.ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType)
case ctx.Repo.TreePath != "": } else {
feed.ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) feed.ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType)
} }
return return

View file

@ -1462,8 +1462,8 @@ func registerRoutes(m *web.Route) {
m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed) m.Get("/rss/branch/*", repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed("rss"))
m.Get("/atom/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed) m.Get("/atom/branch/*", repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed("atom"))
m.Group("/src", func() { m.Group("/src", func() {
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home) m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home)

View file

@ -7,15 +7,19 @@ import (
"net/http" "net/http"
"testing" "testing"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestFeed(t *testing.T) { func TestFeed(t *testing.T) {
defer tests.PrepareTestEnv(t)()
t.Run("User", func(t *testing.T) { t.Run("User", func(t *testing.T) {
t.Run("Atom", func(t *testing.T) { t.Run("Atom", func(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2.atom") req := NewRequest(t, "GET", "/user2.atom")
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
@ -25,7 +29,7 @@ func TestFeed(t *testing.T) {
}) })
t.Run("RSS", func(t *testing.T) { t.Run("RSS", func(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2.rss") req := NewRequest(t, "GET", "/user2.rss")
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
@ -34,4 +38,51 @@ func TestFeed(t *testing.T) {
assert.Contains(t, data, `<rss version="2.0"`) assert.Contains(t, data, `<rss version="2.0"`)
}) })
}) })
t.Run("Repo", func(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
t.Run("Atom", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/atom/branch/master")
resp := MakeRequest(t, req, http.StatusOK)
data := resp.Body.String()
assert.Contains(t, data, `<feed xmlns="http://www.w3.org/2005/Atom"`)
})
t.Run("RSS", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/rss/branch/master")
resp := MakeRequest(t, req, http.StatusOK)
data := resp.Body.String()
assert.Contains(t, data, `<rss version="2.0"`)
})
})
t.Run("Empty", func(t *testing.T) {
err := user_model.UpdateUserCols(db.DefaultContext, &user_model.User{ID: 30, ProhibitLogin: false}, "prohibit_login")
assert.NoError(t, err)
session := loginUser(t, "user30")
t.Run("Atom", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user30/empty/atom/branch/master")
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", "/user30/empty.atom/src/branch/master")
session.MakeRequest(t, req, http.StatusNotFound)
})
t.Run("RSS", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user30/empty/rss/branch/master")
session.MakeRequest(t, req, http.StatusNotFound)
req = NewRequest(t, "GET", "/user30/empty.rss/src/branch/master")
session.MakeRequest(t, req, http.StatusNotFound)
})
})
})
} }