Skip to content

Commit c1f76ae

Browse files
Use raw Wiki links for non-renderable Wiki files (#30273)
In Wiki pages, short-links created to local Wiki files were always expanded as regular Wiki Links. In particular, if a link wanted to point to a file that Gitea doesn't know how to render (e.g, a .zip file), a user following the link would be silently redirected to the Wiki's home page. This change makes short-links* in Wiki pages be expanded to raw wiki links, so these local wiki files may be accessed without manually accessing their URL. * only short-links ending in a file extension that isn't renderable are affected. Closes #27121. Signed-off-by: Rafael Girão <[email protected]> Co-authored-by: silverwind <[email protected]>
1 parent 50099d7 commit c1f76ae

12 files changed

+65
-23
lines changed

modules/markup/html.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,8 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
709709

710710
name += tail
711711
image := false
712-
switch ext := filepath.Ext(link); ext {
712+
ext := filepath.Ext(link)
713+
switch ext {
713714
// fast path: empty string, ignore
714715
case "":
715716
// leave image as false
@@ -767,11 +768,26 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
767768
}
768769
} else {
769770
if !absoluteLink {
771+
var base string
770772
if ctx.IsWiki {
771-
link = util.URLJoin(ctx.Links.WikiLink(), link)
773+
switch ext {
774+
case "":
775+
// no file extension, create a regular wiki link
776+
base = ctx.Links.WikiLink()
777+
default:
778+
// we have a file extension:
779+
// return a regular wiki link if it's a renderable file (extension),
780+
// raw link otherwise
781+
if Type(link) != "" {
782+
base = ctx.Links.WikiLink()
783+
} else {
784+
base = ctx.Links.WikiRawLink()
785+
}
786+
}
772787
} else {
773-
link = util.URLJoin(ctx.Links.SrcLink(), link)
788+
base = ctx.Links.SrcLink()
774789
}
790+
link = util.URLJoin(base, link)
775791
}
776792
childNode.Type = html.TextNode
777793
childNode.Data = name

modules/markup/html_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ func TestRender_ShortLinks(t *testing.T) {
427427
otherImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+Other.jpg")
428428
encodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+%23.jpg")
429429
notencodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "some", "path", "Link+#.jpg")
430+
renderableFileURL := util.URLJoin(tree, "markdown_file.md")
431+
renderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "markdown_file.md")
432+
unrenderableFileURL := util.URLJoin(tree, "file.zip")
433+
unrenderableFileURLWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "file.zip")
430434
favicon := "http://google.com/favicon.ico"
431435

432436
test(
@@ -481,6 +485,14 @@ func TestRender_ShortLinks(t *testing.T) {
481485
"[[Link]] [[Other Link]] [[Link?]]",
482486
`<p><a href="`+url+`" rel="nofollow">Link</a> <a href="`+otherURL+`" rel="nofollow">Other Link</a> <a href="`+encodedURL+`" rel="nofollow">Link?</a></p>`,
483487
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a> <a href="`+otherURLWiki+`" rel="nofollow">Other Link</a> <a href="`+encodedURLWiki+`" rel="nofollow">Link?</a></p>`)
488+
test(
489+
"[[markdown_file.md]]",
490+
`<p><a href="`+renderableFileURL+`" rel="nofollow">markdown_file.md</a></p>`,
491+
`<p><a href="`+renderableFileURLWiki+`" rel="nofollow">markdown_file.md</a></p>`)
492+
test(
493+
"[[file.zip]]",
494+
`<p><a href="`+unrenderableFileURL+`" rel="nofollow">file.zip</a></p>`,
495+
`<p><a href="`+unrenderableFileURLWiki+`" rel="nofollow">file.zip</a></p>`)
484496
test(
485497
"[[Link #.jpg]]",
486498
`<p><a href="`+encodedImgurl+`" rel="nofollow"><img src="`+encodedImgurl+`" title="Link #.jpg" alt="Link #.jpg"/></a></p>`,

modules/markup/markdown/markdown_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -653,9 +653,9 @@ space</p>
653653
Expected: `<p>space @mention-user<br/>
654654
/just/a/path.bin<br/>
655655
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
656-
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
656+
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
657657
<a href="https://example.com" rel="nofollow">remote link</a><br/>
658-
<a href="/wiki/file.bin" rel="nofollow">local link</a><br/>
658+
<a href="/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
659659
<a href="https://example.com" rel="nofollow">remote link</a><br/>
660660
<a href="/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/image.jpg" alt="local image"/></a><br/>
661661
<a href="/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/wiki/raw/path/file" alt="local image"/></a><br/>
@@ -711,9 +711,9 @@ space</p>
711711
Expected: `<p>space @mention-user<br/>
712712
/just/a/path.bin<br/>
713713
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
714-
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
714+
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
715715
<a href="https://example.com" rel="nofollow">remote link</a><br/>
716-
<a href="https://gitea.io/wiki/file.bin" rel="nofollow">local link</a><br/>
716+
<a href="https://gitea.io/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
717717
<a href="https://example.com" rel="nofollow">remote link</a><br/>
718718
<a href="https://gitea.io/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/image.jpg" alt="local image"/></a><br/>
719719
<a href="https://gitea.io/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/wiki/raw/path/file" alt="local image"/></a><br/>
@@ -769,9 +769,9 @@ space</p>
769769
Expected: `<p>space @mention-user<br/>
770770
/just/a/path.bin<br/>
771771
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
772-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
772+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
773773
<a href="https://example.com" rel="nofollow">remote link</a><br/>
774-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
774+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
775775
<a href="https://example.com" rel="nofollow">remote link</a><br/>
776776
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
777777
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
@@ -829,9 +829,9 @@ space</p>
829829
Expected: `<p>space @mention-user<br/>
830830
/just/a/path.bin<br/>
831831
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
832-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
832+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
833833
<a href="https://example.com" rel="nofollow">remote link</a><br/>
834-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
834+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
835835
<a href="https://example.com" rel="nofollow">remote link</a><br/>
836836
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
837837
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
@@ -889,9 +889,9 @@ space</p>
889889
Expected: `<p>space @mention-user<br/>
890890
/just/a/path.bin<br/>
891891
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
892-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
892+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
893893
<a href="https://example.com" rel="nofollow">remote link</a><br/>
894-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
894+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
895895
<a href="https://example.com" rel="nofollow">remote link</a><br/>
896896
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
897897
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>
@@ -951,9 +951,9 @@ space</p>
951951
Expected: `<p>space @mention-user<br/>
952952
/just/a/path.bin<br/>
953953
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
954-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
954+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
955955
<a href="https://example.com" rel="nofollow">remote link</a><br/>
956-
<a href="/relative/path/wiki/file.bin" rel="nofollow">local link</a><br/>
956+
<a href="/relative/path/wiki/raw/file.bin" rel="nofollow">local link</a><br/>
957957
<a href="https://example.com" rel="nofollow">remote link</a><br/>
958958
<a href="/relative/path/wiki/raw/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/image.jpg" alt="local image"/></a><br/>
959959
<a href="/relative/path/wiki/raw/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/wiki/raw/path/file" alt="local image"/></a><br/>

modules/markup/markdown/transform_link.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package markdown
55

66
import (
7+
"path/filepath"
8+
79
"code.gitea.io/gitea/modules/markup"
810
giteautil "code.gitea.io/gitea/modules/util"
911

@@ -18,7 +20,16 @@ func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link, r
1820
if !isAnchorFragment && !markup.IsFullURLBytes(link) {
1921
base := ctx.Links.Base
2022
if ctx.IsWiki {
21-
base = ctx.Links.WikiLink()
23+
if filepath.Ext(string(link)) == "" {
24+
// This link doesn't have a file extension - assume a regular wiki link
25+
base = ctx.Links.WikiLink()
26+
} else if markup.Type(string(link)) != "" {
27+
// If it's a file type we can render, use a regular wiki link
28+
base = ctx.Links.WikiLink()
29+
} else {
30+
// Otherwise, use a raw link instead
31+
base = ctx.Links.WikiRawLink()
32+
}
2233
} else if ctx.Links.HasBranchInfo() {
2334
base = ctx.Links.SrcLink()
2435
}

routers/web/repo/wiki_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,13 @@ func TestDeleteWikiPagePost(t *testing.T) {
200200

201201
func TestWikiRaw(t *testing.T) {
202202
for filepath, filetype := range map[string]string{
203-
"jpeg.jpg": "image/jpeg",
204-
"images/jpeg.jpg": "image/jpeg",
205-
"Page With Spaced Name": "text/plain; charset=utf-8",
206-
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
207-
"Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo
208-
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
203+
"jpeg.jpg": "image/jpeg",
204+
"images/jpeg.jpg": "image/jpeg",
205+
"files/Non-Renderable-File.zip": "application/octet-stream",
206+
"Page With Spaced Name": "text/plain; charset=utf-8",
207+
"Page-With-Spaced-Name": "text/plain; charset=utf-8",
208+
"Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo
209+
"Page-With-Spaced-Name.md": "text/plain; charset=utf-8",
209210
} {
210211
unittest.PrepareTestEnv(t)
211212

tests/gitea-repositories-meta/user2/repo1.wiki.git/objects/a5/bbc0fd39a696feabed2d4cccaf05abbcaf3b02

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
x��Kn� D��죱�v�EQ��~n�@3F� ��r�\,d��^�T��S�ϏGj|��K+D����$2`�4��Y��Y�u{�Xho\���u4E;k- P4�Q^H�84��lk.��i�_��|g�V�v��=����|�-U�q8�;�ZJ��,��Nn�_����0�a�3���ҿ T�mķ�q�1m�؍b�򵵣^���z��/����_�5�zR'-'�~�tl�
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0dca5bd9b5d7ef937710e056f575e86c0184ba85
1+
a5bbc0fd39a696feabed2d4cccaf05abbcaf3b02

tests/integration/git_clone_wiki_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func TestRepoCloneWiki(t *testing.T) {
4545
assertFileExist(t, filepath.Join(dstPath, "Page-With-Image.md"))
4646
assertFileExist(t, filepath.Join(dstPath, "Page-With-Spaced-Name.md"))
4747
assertFileExist(t, filepath.Join(dstPath, "images"))
48+
assertFileExist(t, filepath.Join(dstPath, "files/Non-Renderable-File.zip"))
4849
assertFileExist(t, filepath.Join(dstPath, "jpeg.jpg"))
4950
})
5051
})

0 commit comments

Comments
 (0)