]> source.dussan.org Git - gitea.git/commitdiff
Fix orgmode link resolving (#29024)
authorwxiaoguang <wxiaoguang@gmail.com>
Wed, 7 Feb 2024 08:32:31 +0000 (16:32 +0800)
committerGitHub <noreply@github.com>
Wed, 7 Feb 2024 08:32:31 +0000 (08:32 +0000)
Fix #28974

Add some new tests and fix some legacy unclear tests.

modules/markup/orgmode/orgmode.go
modules/markup/orgmode/orgmode_test.go

index abc641fbe2dfc7790f099cd6284f8c34267fd1db..ac1cedff6d4c1c4023f732e018832d68bf9276c0 100644 (file)
@@ -133,18 +133,18 @@ type Writer struct {
        Ctx *markup.RenderContext
 }
 
-const mailto = "mailto:"
-
-func (r *Writer) resolveLink(l org.RegularLink) string {
-       link := html.EscapeString(l.URL)
-       if l.Protocol == "file" {
-               link = link[len("file:"):]
-       }
-       if len(link) > 0 && !markup.IsLinkStr(link) &&
-               link[0] != '#' && !strings.HasPrefix(link, mailto) {
+func (r *Writer) resolveLink(kind, link string) string {
+       link = strings.TrimPrefix(link, "file:")
+       if !strings.HasPrefix(link, "#") && // not a URL fragment
+               !markup.IsLinkStr(link) && // not an absolute URL
+               !strings.HasPrefix(link, "mailto:") {
+               if kind == "regular" {
+                       // orgmode reports the link kind as "regular" for "[[ImageLink.svg][The Image Desc]]"
+                       // so we need to try to guess the link kind again here
+                       kind = org.RegularLink{URL: link}.Kind()
+               }
                base := r.Ctx.Links.Base
-               switch l.Kind() {
-               case "image", "video":
+               if kind == "image" || kind == "video" {
                        base = r.Ctx.Links.ResolveMediaLink(r.Ctx.IsWiki)
                }
                link = util.URLJoin(base, link)
@@ -154,29 +154,29 @@ func (r *Writer) resolveLink(l org.RegularLink) string {
 
 // WriteRegularLink renders images, links or videos
 func (r *Writer) WriteRegularLink(l org.RegularLink) {
-       link := r.resolveLink(l)
+       link := r.resolveLink(l.Kind(), l.URL)
 
        // Inspired by https://github.com/niklasfasching/go-org/blob/6eb20dbda93cb88c3503f7508dc78cbbc639378f/org/html_writer.go#L406-L427
        switch l.Kind() {
        case "image":
                if l.Description == nil {
-                       fmt.Fprintf(r, `<img src="%s" alt="%s" />`, link, link)
+                       _, _ = fmt.Fprintf(r, `<img src="%s" alt="%s" />`, link, link)
                } else {
-                       imageSrc := r.resolveLink(l.Description[0].(org.RegularLink))
-                       fmt.Fprintf(r, `<a href="%s"><img src="%s" alt="%s" /></a>`, link, imageSrc, imageSrc)
+                       imageSrc := r.resolveLink(l.Kind(), org.String(l.Description...))
+                       _, _ = fmt.Fprintf(r, `<a href="%s"><img src="%s" alt="%s" /></a>`, link, imageSrc, imageSrc)
                }
        case "video":
                if l.Description == nil {
-                       fmt.Fprintf(r, `<video src="%s">%s</video>`, link, link)
+                       _, _ = fmt.Fprintf(r, `<video src="%s">%s</video>`, link, link)
                } else {
-                       videoSrc := r.resolveLink(l.Description[0].(org.RegularLink))
-                       fmt.Fprintf(r, `<a href="%s"><video src="%s">%s</video></a>`, link, videoSrc, videoSrc)
+                       videoSrc := r.resolveLink(l.Kind(), org.String(l.Description...))
+                       _, _ = fmt.Fprintf(r, `<a href="%s"><video src="%s">%s</video></a>`, link, videoSrc, videoSrc)
                }
        default:
                description := link
                if l.Description != nil {
                        description = r.WriteNodesAsString(l.Description...)
                }
-               fmt.Fprintf(r, `<a href="%s">%s</a>`, link, description)
+               _, _ = fmt.Fprintf(r, `<a href="%s">%s</a>`, link, description)
        }
 }
index abf5ca8fcf385ecf14b452defbdbff1005d3c713..95f53c9cc9ff51be0b3d4dde73209534340c6b9f 100644 (file)
@@ -10,26 +10,21 @@ import (
        "code.gitea.io/gitea/modules/git"
        "code.gitea.io/gitea/modules/markup"
        "code.gitea.io/gitea/modules/setting"
-       "code.gitea.io/gitea/modules/util"
 
        "github.com/stretchr/testify/assert"
 )
 
-const (
-       AppURL    = "http://localhost:3000/"
-       Repo      = "gogits/gogs"
-       AppSubURL = AppURL + Repo + "/"
-)
+const AppURL = "http://localhost:3000/"
 
 func TestRender_StandardLinks(t *testing.T) {
        setting.AppURL = AppURL
-       setting.AppSubURL = AppSubURL
 
        test := func(input, expected string) {
                buffer, err := RenderString(&markup.RenderContext{
                        Ctx: git.DefaultContext,
                        Links: markup.Links{
-                               Base: setting.AppSubURL,
+                               Base:       "/relative-path",
+                               BranchPath: "branch/main",
                        },
                }, input)
                assert.NoError(t, err)
@@ -38,32 +33,30 @@ func TestRender_StandardLinks(t *testing.T) {
 
        test("[[https://google.com/]]",
                `<p><a href="https://google.com/">https://google.com/</a></p>`)
-
-       lnk := util.URLJoin(AppSubURL, "WikiPage")
-       test("[[WikiPage][WikiPage]]",
-               `<p><a href="`+lnk+`">WikiPage</a></p>`)
+       test("[[WikiPage][The WikiPage Desc]]",
+               `<p><a href="/relative-path/WikiPage">The WikiPage Desc</a></p>`)
+       test("[[ImageLink.svg][The Image Desc]]",
+               `<p><a href="/relative-path/media/branch/main/ImageLink.svg">The Image Desc</a></p>`)
 }
 
 func TestRender_Media(t *testing.T) {
        setting.AppURL = AppURL
-       setting.AppSubURL = AppSubURL
 
        test := func(input, expected string) {
                buffer, err := RenderString(&markup.RenderContext{
                        Ctx: git.DefaultContext,
                        Links: markup.Links{
-                               Base: setting.AppSubURL,
+                               Base: "./relative-path",
                        },
                }, input)
                assert.NoError(t, err)
                assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
        }
 
-       url := "../../.images/src/02/train.jpg"
-       result := util.URLJoin(AppSubURL, url)
-
-       test("[[file:"+url+"]]",
-               `<p><img src="`+result+`" alt="`+result+`" /></p>`)
+       test("[[file:../../.images/src/02/train.jpg]]",
+               `<p><img src=".images/src/02/train.jpg" alt=".images/src/02/train.jpg" /></p>`)
+       test("[[file:train.jpg]]",
+               `<p><img src="relative-path/train.jpg" alt="relative-path/train.jpg" /></p>`)
 
        // With description.
        test("[[https://example.com][https://example.com/example.svg]]",
@@ -80,11 +73,20 @@ func TestRender_Media(t *testing.T) {
                `<p><img src="https://example.com/example.svg" alt="https://example.com/example.svg" /></p>`)
        test("[[https://example.com/example.mp4]]",
                `<p><video src="https://example.com/example.mp4">https://example.com/example.mp4</video></p>`)
+
+       // test [[LINK][DESCRIPTION]] syntax with "file:" prefix
+       test(`[[https://example.com/][file:https://example.com/foo%20bar.svg]]`,
+               `<p><a href="https://example.com/"><img src="https://example.com/foo%20bar.svg" alt="https://example.com/foo%20bar.svg" /></a></p>`)
+       test(`[[file:https://example.com/foo%20bar.svg][Goto Image]]`,
+               `<p><a href="https://example.com/foo%20bar.svg">Goto Image</a></p>`)
+       test(`[[file:https://example.com/link][https://example.com/image.jpg]]`,
+               `<p><a href="https://example.com/link"><img src="https://example.com/image.jpg" alt="https://example.com/image.jpg" /></a></p>`)
+       test(`[[file:https://example.com/link][file:https://example.com/image.jpg]]`,
+               `<p><a href="https://example.com/link"><img src="https://example.com/image.jpg" alt="https://example.com/image.jpg" /></a></p>`)
 }
 
 func TestRender_Source(t *testing.T) {
        setting.AppURL = AppURL
-       setting.AppSubURL = AppSubURL
 
        test := func(input, expected string) {
                buffer, err := RenderString(&markup.RenderContext{