aboutsummaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorGiteabot <teabot@gitea.io>2024-08-17 11:19:26 +0800
committerGitHub <noreply@github.com>2024-08-17 03:19:26 +0000
commit3fe1f732686989095abd25599c1dc75bda46246d (patch)
treeb54dcd7471942f88cfc37b0e4c6c8b86d6ad9b5b /routers
parent1cf8f69b3840b04270042c53e3959e1caa623777 (diff)
downloadgitea-3fe1f732686989095abd25599c1dc75bda46246d.tar.gz
gitea-3fe1f732686989095abd25599c1dc75bda46246d.zip
Fix raw wiki links (#31825) (#31845)
Backport #31825 by @Zettat123 Fix #31395 This regression is introduced by #30273. To find out how GitHub handles this case, I did [some tests](https://github.com/go-gitea/gitea/issues/31395#issuecomment-2278929115). I use redirect in this PR instead of checking if the corresponding `.md` file exists when rendering the link because GitHub also uses redirect. With this PR, there is no need to resolve the raw wiki link when rendering a wiki page. If a wiki link points to a raw file, access will be redirected to the raw link. --------- Co-authored-by: Zettat123 <zettat123@gmail.com> Co-authored-by: yp05327 <576951401@qq.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'routers')
-rw-r--r--routers/web/repo/wiki.go64
-rw-r--r--routers/web/repo/wiki_test.go14
2 files changed, 68 insertions, 10 deletions
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index 13b6a7b8e3..d2056353d8 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -138,18 +138,41 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
return content
}
-// wikiContentsByName returns the contents of a wiki page, along with a boolean
-// indicating whether the page exists. Writes to ctx if an error occurs.
-func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) {
+// wikiEntryByName returns the entry of a wiki page, along with a boolean
+// indicating whether the entry exists. Writes to ctx if an error occurs.
+// The last return value indicates whether the file should be returned as a raw file
+func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) (*git.TreeEntry, string, bool, bool) {
+ isRaw := false
gitFilename := wiki_service.WebPathToGitPath(wikiName)
entry, err := findEntryForFile(commit, gitFilename)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findEntryForFile", err)
- return nil, nil, "", false
- } else if entry == nil {
+ return nil, "", false, false
+ }
+ if entry == nil {
+ // check if the file without ".md" suffix exists
+ gitFilename := strings.TrimSuffix(gitFilename, ".md")
+ entry, err = findEntryForFile(commit, gitFilename)
+ if err != nil && !git.IsErrNotExist(err) {
+ ctx.ServerError("findEntryForFile", err)
+ return nil, "", false, false
+ }
+ isRaw = true
+ }
+ if entry == nil {
+ return nil, "", true, false
+ }
+ return entry, gitFilename, false, isRaw
+}
+
+// wikiContentsByName returns the contents of a wiki page, along with a boolean
+// indicating whether the page exists. Writes to ctx if an error occurs.
+func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) {
+ entry, gitFilename, noEntry, _ := wikiEntryByName(ctx, commit, wikiName)
+ if entry == nil {
return nil, nil, "", true
}
- return wikiContentsByEntry(ctx, entry), entry, gitFilename, false
+ return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry
}
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
@@ -215,11 +238,14 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
isSideBar := pageName == "_Sidebar"
isFooter := pageName == "_Footer"
- // lookup filename in wiki - get filecontent, gitTree entry , real filename
- data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
+ // lookup filename in wiki - get gitTree entry , real filename
+ entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
+ if isRaw {
+ ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName)))
+ }
if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
@@ -227,6 +253,15 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
+ // get filecontent
+ data := wikiContentsByEntry(ctx, entry)
+ if ctx.Written() {
+ if wikiRepo != nil {
+ wikiRepo.Close()
+ }
+ return nil, nil
+ }
+
var sidebarContent []byte
if !isSideBar {
sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar")
@@ -442,15 +477,24 @@ func renderEditPage(ctx *context.Context) {
ctx.Data["Title"] = displayName
ctx.Data["title"] = displayName
- // lookup filename in wiki - get filecontent, gitTree entry , real filename
- data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
+ // lookup filename in wiki - gitTree entry , real filename
+ entry, _, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
+ if isRaw {
+ ctx.Error(http.StatusForbidden, "Editing of raw wiki files is not allowed")
+ }
if entry == nil || ctx.Written() {
return
}
+ // get filecontent
+ data := wikiContentsByEntry(ctx, entry)
+ if ctx.Written() {
+ return
+ }
+
ctx.Data["content"] = string(data)
ctx.Data["sidebarPresent"] = false
ctx.Data["sidebarContent"] = ""
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 4602dcfeb4..86971f15f1 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -87,6 +87,13 @@ func TestWiki(t *testing.T) {
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
+
+ ctx, _ = contexttest.MockContext(t, "user2/repo1/jpeg.jpg")
+ ctx.SetParams("*", "jpeg.jpg")
+ contexttest.LoadRepo(t, ctx, 1)
+ Wiki(ctx)
+ assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
+ assert.Equal(t, "/user2/repo1/wiki/raw/jpeg.jpg", ctx.Resp.Header().Get("Location"))
}
func TestWikiPages(t *testing.T) {
@@ -160,6 +167,13 @@ func TestEditWiki(t *testing.T) {
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"])
+
+ ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit")
+ ctx.SetParams("*", "jpeg.jpg")
+ contexttest.LoadUser(t, ctx, 2)
+ contexttest.LoadRepo(t, ctx, 1)
+ EditWiki(ctx)
+ assert.EqualValues(t, http.StatusForbidden, ctx.Resp.Status())
}
func TestEditWikiPost(t *testing.T) {