Skip to content

Commit 8dec66e

Browse files
committed
fix
1 parent 4b6eb46 commit 8dec66e

File tree

10 files changed

+58
-73
lines changed

10 files changed

+58
-73
lines changed

modules/markup/html.go

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -761,10 +761,10 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
761761
if image {
762762
link = strings.ReplaceAll(link, " ", "+")
763763
} else {
764-
link = strings.ReplaceAll(link, " ", "-")
764+
link = strings.ReplaceAll(link, " ", "-") // FIXME: it should support dashes in the link, eg: "the-dash-support.-"
765765
}
766766
if !strings.Contains(link, "/") {
767-
link = url.PathEscape(link)
767+
link = url.PathEscape(link) // FIXME: it doesn't seem right and it might cause double-escaping
768768
}
769769
}
770770
if image {
@@ -796,28 +796,7 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
796796
childNode.Attr = childNode.Attr[:2]
797797
}
798798
} else {
799-
if !absoluteLink {
800-
var base string
801-
if ctx.IsWiki {
802-
switch ext {
803-
case "":
804-
// no file extension, create a regular wiki link
805-
base = ctx.Links.WikiLink()
806-
default:
807-
// we have a file extension:
808-
// return a regular wiki link if it's a renderable file (extension),
809-
// raw link otherwise
810-
if Type(link) != "" {
811-
base = ctx.Links.WikiLink()
812-
} else {
813-
base = ctx.Links.WikiRawLink()
814-
}
815-
}
816-
} else {
817-
base = ctx.Links.SrcLink()
818-
}
819-
link = util.URLJoin(base, link)
820-
}
799+
link, _ = ResolveLink(ctx, link, "")
821800
childNode.Type = html.TextNode
822801
childNode.Data = name
823802
}

modules/markup/html_link.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package markup
5+
6+
import (
7+
"path"
8+
9+
"code.gitea.io/gitea/modules/util"
10+
)
11+
12+
func ResolveLink(ctx *RenderContext, link, userContentAnchorPrefix string) (result string, resolved bool) {
13+
isAnchorFragment := link != "" && link[0] == '#'
14+
if !isAnchorFragment && !IsFullURLString(link) {
15+
linkBase := ctx.Links.Base
16+
if ctx.IsWiki {
17+
if ext := path.Ext(link); ext == "" || ext == ".-" {
18+
linkBase = ctx.Links.WikiLink() // the link is for a wiki page
19+
} else if DetectMarkupTypeByFileName(link) != "" {
20+
linkBase = ctx.Links.WikiLink() // the link is renderable as a wiki page
21+
} else {
22+
linkBase = ctx.Links.WikiRawLink() // otherwise, use a raw link instead to view&download medias
23+
}
24+
} else if ctx.Links.BranchPath != "" || ctx.Links.TreePath != "" {
25+
// if there is no BranchPath, then the link will be something like "/owner/repo/src/{the-file-path}"
26+
// 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}"
27+
linkBase = ctx.Links.SrcLink()
28+
}
29+
link, resolved = util.URLJoin(linkBase, link), true
30+
}
31+
if isAnchorFragment && userContentAnchorPrefix != "" {
32+
link, resolved = userContentAnchorPrefix+link[1:], true
33+
}
34+
return link, resolved
35+
}

modules/markup/html_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ func TestRender_ShortLinks(t *testing.T) {
455455
"[[Link]]",
456456
`<p><a href="`+url+`" rel="nofollow">Link</a></p>`,
457457
`<p><a href="`+urlWiki+`" rel="nofollow">Link</a></p>`)
458+
test(
459+
"[[Link.-]]",
460+
`<p><a href="http://localhost:3000/test-owner/test-repo/src/master/Link.-" rel="nofollow">Link.-</a></p>`,
461+
`<p><a href="http://localhost:3000/test-owner/test-repo/wiki/Link.-" rel="nofollow">Link.-</a></p>`)
458462
test(
459463
"[[Link.jpg]]",
460464
`<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" title="Link.jpg" alt="Link.jpg"/></a></p>`,

modules/markup/markdown/markdown_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ [email protected]
635635
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
636636
<a href="/file.bin" rel="nofollow">local link</a><br/>
637637
<a href="https://example.com" rel="nofollow">remote link</a><br/>
638-
<a href="/src/file.bin" rel="nofollow">local link</a><br/>
638+
<a href="/file.bin" rel="nofollow">local link</a><br/>
639639
<a href="https://example.com" rel="nofollow">remote link</a><br/>
640640
<a href="/image.jpg" target="_blank" rel="nofollow noopener"><img src="/image.jpg" alt="local image"/></a><br/>
641641
<a href="/path/file" target="_blank" rel="nofollow noopener"><img src="/path/file" alt="local image"/></a><br/>
@@ -691,7 +691,7 @@ space</p>
691691
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
692692
<a href="https://gitea.io/file.bin" rel="nofollow">local link</a><br/>
693693
<a href="https://example.com" rel="nofollow">remote link</a><br/>
694-
<a href="https://gitea.io/src/file.bin" rel="nofollow">local link</a><br/>
694+
<a href="https://gitea.io/file.bin" rel="nofollow">local link</a><br/>
695695
<a href="https://example.com" rel="nofollow">remote link</a><br/>
696696
<a href="https://gitea.io/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/image.jpg" alt="local image"/></a><br/>
697697
<a href="https://gitea.io/path/file" target="_blank" rel="nofollow noopener"><img src="https://gitea.io/path/file" alt="local image"/></a><br/>
@@ -749,7 +749,7 @@ space</p>
749749
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
750750
<a href="/relative/path/file.bin" rel="nofollow">local link</a><br/>
751751
<a href="https://example.com" rel="nofollow">remote link</a><br/>
752-
<a href="/relative/path/src/file.bin" rel="nofollow">local link</a><br/>
752+
<a href="/relative/path/file.bin" rel="nofollow">local link</a><br/>
753753
<a href="https://example.com" rel="nofollow">remote link</a><br/>
754754
<a href="/relative/path/image.jpg" target="_blank" rel="nofollow noopener"><img src="/relative/path/image.jpg" alt="local image"/></a><br/>
755755
<a href="/relative/path/path/file" target="_blank" rel="nofollow noopener"><img src="/relative/path/path/file" alt="local image"/></a><br/>
@@ -866,7 +866,7 @@ space</p>
866866
Expected: `<p>space @mention-user<br/>
867867
/just/a/path.bin<br/>
868868
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a><br/>
869-
<a href="/user/repo/file.bin" rel="nofollow">local link</a><br/>
869+
<a href="/user/repo/src/sub/folder/file.bin" rel="nofollow">local link</a><br/>
870870
<a href="https://example.com" rel="nofollow">remote link</a><br/>
871871
<a href="/user/repo/src/sub/folder/file.bin" rel="nofollow">local link</a><br/>
872872
<a href="https://example.com" rel="nofollow">remote link</a><br/>
@@ -984,7 +984,7 @@ space</p>
984984
for i, c := range cases {
985985
result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input)
986986
assert.NoError(t, err, "Unexpected error in testcase: %v", i)
987-
assert.Equal(t, template.HTML(c.Expected), result, "Unexpected result in testcase %v", i)
987+
assert.Equal(t, c.Expected, string(result), "Unexpected result in testcase %v", i)
988988
}
989989
}
990990

modules/markup/markdown/transform_link.go

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,13 @@
44
package markdown
55

66
import (
7-
"path/filepath"
8-
97
"code.gitea.io/gitea/modules/markup"
10-
giteautil "code.gitea.io/gitea/modules/util"
118

129
"github.com/yuin/goldmark/ast"
1310
)
1411

1512
func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link) {
16-
// Links need their href to munged to be a real value
17-
link := v.Destination
18-
isAnchorFragment := len(link) > 0 && link[0] == '#'
19-
if !isAnchorFragment && !markup.IsFullURLBytes(link) {
20-
base := ctx.Links.Base
21-
if ctx.IsWiki {
22-
if filepath.Ext(string(link)) == "" {
23-
// This link doesn't have a file extension - assume a regular wiki link
24-
base = ctx.Links.WikiLink()
25-
} else if markup.Type(string(link)) != "" {
26-
// If it's a file type we can render, use a regular wiki link
27-
base = ctx.Links.WikiLink()
28-
} else {
29-
// Otherwise, use a raw link instead
30-
base = ctx.Links.WikiRawLink()
31-
}
32-
} else if ctx.Links.HasBranchInfo() {
33-
base = ctx.Links.SrcLink()
34-
}
35-
link = []byte(giteautil.URLJoin(base, string(link)))
36-
}
37-
if isAnchorFragment {
38-
link = []byte("#user-content-" + string(link)[1:])
13+
if link, resolved := markup.ResolveLink(ctx, string(v.Destination), "#user-content-"); resolved {
14+
v.Destination = []byte(link)
3915
}
40-
v.Destination = link
4116
}

modules/markup/renderer.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -372,22 +372,14 @@ func renderFile(ctx *RenderContext, input io.Reader, output io.Writer) error {
372372
return ErrUnsupportedRenderExtension{extension}
373373
}
374374

375-
// Type returns if markup format via the filename
376-
func Type(filename string) string {
375+
// DetectMarkupTypeByFileName returns the possible markup format type via the filename
376+
func DetectMarkupTypeByFileName(filename string) string {
377377
if parser := GetRendererByFileName(filename); parser != nil {
378378
return parser.Name()
379379
}
380380
return ""
381381
}
382382

383-
// IsMarkupFile reports whether file is a markup type file
384-
func IsMarkupFile(name, markup string) bool {
385-
if parser := GetRendererByFileName(name); parser != nil {
386-
return parser.Name() == markup
387-
}
388-
return false
389-
}
390-
391383
func PreviewableExtensions() []string {
392384
extensions := make([]string, 0, len(extRenderers))
393385
for extension := range extRenderers {

modules/templates/util_render_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func TestRenderMarkdownToHtml(t *testing.T) {
174174
<a href="https://example.com/file.bin" rel="nofollow">https://example.com/file.bin</a>
175175
<a href="/file.bin" rel="nofollow">local link</a>
176176
<a href="https://example.com" rel="nofollow">remote link</a>
177-
<a href="/src/file.bin" rel="nofollow">local link</a>
177+
<a href="/file.bin" rel="nofollow">local link</a>
178178
<a href="https://example.com" rel="nofollow">remote link</a>
179179
<a href="/image.jpg" target="_blank" rel="nofollow noopener"><img src="/image.jpg" alt="local image"/></a>
180180
<a href="https://example.com/image.jpg" target="_blank" rel="nofollow noopener"><img src="https://example.com/image.jpg" alt="remote image"/></a>
@@ -190,7 +190,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
190190
#123
191191
space</p>
192192
`
193-
assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput()))
193+
assert.Equal(t, expected, string(RenderMarkdownToHtml(context.Background(), testInput())))
194194
}
195195

196196
func TestRenderLabels(t *testing.T) {

routers/web/repo/render.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func RenderFile(ctx *context.Context) {
4747
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
4848
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts")
4949

50-
if markupType := markup.Type(blob.Name()); markupType == "" {
50+
if markupType := markup.DetectMarkupTypeByFileName(blob.Name()); markupType == "" {
5151
if isTextFile {
5252
_, _ = io.Copy(ctx.Resp, rd)
5353
} else {

routers/web/repo/view.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
307307

308308
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
309309

310-
if markupType := markup.Type(readmeFile.Name()); markupType != "" {
310+
if markupType := markup.DetectMarkupTypeByFileName(readmeFile.Name()); markupType != "" {
311311
ctx.Data["IsMarkup"] = true
312312
ctx.Data["MarkupType"] = markupType
313313

@@ -499,7 +499,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
499499
readmeExist := util.IsReadmeFileName(blob.Name())
500500
ctx.Data["ReadmeExist"] = readmeExist
501501

502-
markupType := markup.Type(blob.Name())
502+
markupType := markup.DetectMarkupTypeByFileName(blob.Name())
503503
// If the markup is detected by custom markup renderer it should not be reset later on
504504
// to not pass it down to the render context.
505505
detected := false
@@ -607,7 +607,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
607607

608608
// TODO: this logic duplicates with "isRepresentableAsText=true", it is not the same as "LFSFileGet" in "lfs.go"
609609
// It is used by "external renders", markupRender will execute external programs to get rendered content.
610-
if markupType := markup.Type(blob.Name()); markupType != "" {
610+
if markupType := markup.DetectMarkupTypeByFileName(blob.Name()); markupType != "" {
611611
rd := io.MultiReader(bytes.NewReader(buf), dataRc)
612612
ctx.Data["IsMarkup"] = true
613613
ctx.Data["MarkupType"] = markupType

routers/web/repo/wiki.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ func Wiki(ctx *context.Context) {
532532
}
533533

534534
wikiPath := entry.Name()
535-
if markup.Type(wikiPath) != markdown.MarkupName {
535+
if markup.DetectMarkupTypeByFileName(wikiPath) != markdown.MarkupName {
536536
ext := strings.ToUpper(filepath.Ext(wikiPath))
537537
ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
538538
}

0 commit comments

Comments
 (0)