From 0720e83b349e611eca3e11c8dd9a93b80f43194d Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 13 Aug 2024 17:49:53 +0800 Subject: [PATCH 1/5] redirect to raw wiki link --- modules/markup/html_link.go | 12 +++--------- routers/web/repo/wiki.go | 39 +++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/modules/markup/html_link.go b/modules/markup/html_link.go index a41b87e9fa83d..b08613534852d 100644 --- a/modules/markup/html_link.go +++ b/modules/markup/html_link.go @@ -4,8 +4,6 @@ package markup import ( - "path" - "code.gitea.io/gitea/modules/util" ) @@ -14,13 +12,9 @@ func ResolveLink(ctx *RenderContext, link, userContentAnchorPrefix string) (resu if !isAnchorFragment && !IsFullURLString(link) { linkBase := ctx.Links.Base if ctx.IsWiki { - if ext := path.Ext(link); ext == "" || ext == ".-" { - linkBase = ctx.Links.WikiLink() // the link is for a wiki page - } else if DetectMarkupTypeByFileName(link) != "" { - linkBase = ctx.Links.WikiLink() // the link is renderable as a wiki page - } else { - linkBase = ctx.Links.WikiRawLink() // otherwise, use a raw link instead to view&download medias - } + // no need to check if the link should be resolved as a wiki link or a wiki raw link + // just use wiki link here and it will be redirected to a wiki raw link if necessary + linkBase = ctx.Links.WikiLink() } else if ctx.Links.BranchPath != "" || ctx.Links.TreePath != "" { // if there is no BranchPath, then the link will be something like "/owner/repo/src/{the-file-path}" // and then this link will be handled by the "legacy-ref" code and be redirected to the default branch like "/owner/repo/src/branch/main/{the-file-path}" diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 13b6a7b8e3b92..48d16a8a7e80c 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -140,16 +140,29 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte { // 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) { +// the last return value indicates whether the file should be returned as a raw file +func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *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, nil, "", true + return nil, nil, "", false, false } - return wikiContentsByEntry(ctx, entry), entry, gitFilename, 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, nil, "", false, false + } + isRaw = true + } + if entry == nil { + return nil, nil, "", true, false + } + return wikiContentsByEntry(ctx, entry), entry, gitFilename, false, isRaw } func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { @@ -216,10 +229,13 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { isFooter := pageName == "_Footer" // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) + data, entry, pageFilename, noEntry, isRaw := wikiContentsByName(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() @@ -229,7 +245,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { var sidebarContent []byte if !isSideBar { - sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") + sidebarContent, _, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") if ctx.Written() { if wikiRepo != nil { wikiRepo.Close() @@ -242,7 +258,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { var footerContent []byte if !isFooter { - footerContent, _, _, _ = wikiContentsByName(ctx, commit, "_Footer") + footerContent, _, _, _, _ = wikiContentsByName(ctx, commit, "_Footer") if ctx.Written() { if wikiRepo != nil { wikiRepo.Close() @@ -365,7 +381,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) ctx.Data["Reponame"] = ctx.Repo.Repository.Name // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) + data, entry, pageFilename, noEntry, _ := wikiContentsByName(ctx, commit, pageName) if noEntry { ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") } @@ -443,10 +459,13 @@ func renderEditPage(ctx *context.Context) { ctx.Data["title"] = displayName // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName) + data, entry, _, noEntry, isRaw := wikiContentsByName(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 } From 8cd0e0a814482ad56dd58ff4e5ea604c8e206813 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Aug 2024 10:06:59 +0800 Subject: [PATCH 2/5] add wikiEntryByName --- routers/web/repo/wiki.go | 48 +++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 48d16a8a7e80c..6449b18bf1583 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -138,16 +138,16 @@ 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. -// the last return value indicates whether the file should be returned as a raw file -func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool, 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, false + return nil, "", false, false } if entry == nil { // check if the file without ".md" suffix exists @@ -155,14 +155,25 @@ func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_ entry, err = findEntryForFile(commit, gitFilename) if err != nil && !git.IsErrNotExist(err) { ctx.ServerError("findEntryForFile", err) - return nil, nil, "", false, false + 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. +// The last return value indicates whether the file should be returned as a raw file +func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool, bool) { + entry, gitFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, wikiName) if entry == nil { return nil, nil, "", true, false } - return wikiContentsByEntry(ctx, entry), entry, gitFilename, false, isRaw + return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry, isRaw } func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { @@ -228,8 +239,8 @@ 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, isRaw := 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") } @@ -243,6 +254,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") @@ -458,8 +478,8 @@ 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, isRaw := 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") } @@ -470,6 +490,12 @@ func renderEditPage(ctx *context.Context) { return } + // get filecontent + data := wikiContentsByEntry(ctx, entry) + if ctx.Written() { + return + } + ctx.Data["content"] = string(data) ctx.Data["sidebarPresent"] = false ctx.Data["sidebarContent"] = "" From 7fdba9e161eb6705706aff67a81ed36e2d20b974 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Aug 2024 10:18:09 +0800 Subject: [PATCH 3/5] fix wikiContentsByName --- routers/web/repo/wiki.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 6449b18bf1583..d2056353d886d 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -167,13 +167,12 @@ func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_ser // wikiContentsByName returns the contents of a wiki page, along with a boolean // indicating whether the page exists. Writes to ctx if an error occurs. -// The last return value indicates whether the file should be returned as a raw file -func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool, bool) { - entry, gitFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, wikiName) +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, false + return nil, nil, "", true } - return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry, isRaw + return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry } func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { @@ -265,7 +264,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { var sidebarContent []byte if !isSideBar { - sidebarContent, _, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") + sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") if ctx.Written() { if wikiRepo != nil { wikiRepo.Close() @@ -278,7 +277,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { var footerContent []byte if !isFooter { - footerContent, _, _, _, _ = wikiContentsByName(ctx, commit, "_Footer") + footerContent, _, _, _ = wikiContentsByName(ctx, commit, "_Footer") if ctx.Written() { if wikiRepo != nil { wikiRepo.Close() @@ -401,7 +400,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) ctx.Data["Reponame"] = ctx.Repo.Repository.Name // lookup filename in wiki - get filecontent, gitTree entry , real filename - data, entry, pageFilename, noEntry, _ := wikiContentsByName(ctx, commit, pageName) + data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) if noEntry { ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") } From e12249f924cd6f94a4e59b5ca08529e200d58f87 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Aug 2024 11:19:45 +0800 Subject: [PATCH 4/5] fix test --- modules/markup/html_test.go | 2 +- modules/markup/markdown/markdown_test.go | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index c69f3ddd648b7..32858dbd6b31b 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -437,7 +437,7 @@ func TestRender_ShortLinks(t *testing.T) { renderableFileURL := util.URLJoin(tree, "markdown_file.md") renderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "markdown_file.md") unrenderableFileURL := util.URLJoin(tree, "file.zip") - unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "file.zip") + unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "file.zip") favicon := "http://google.com/favicon.ico" test( diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 671276e45c5b9..cfb821ab19ff4 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -672,9 +672,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -730,9 +730,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -788,9 +788,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -848,9 +848,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -908,9 +908,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
@@ -970,9 +970,9 @@ space

Expected: `

space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
-local link
+local link
remote link
local image
local image
From ed7e8584e426fb62d1f0e658ff1823f3981adbfb Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Aug 2024 12:11:02 +0800 Subject: [PATCH 5/5] add more wiki testing --- routers/web/repo/wiki_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index 7de5899e21c1b..b81f2ea02e327 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.SetPathParam("*", "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.SetPathParam("*", "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) {