]> source.dussan.org Git - gitea.git/commitdiff
Fix markdown rendering when mentioning users (#30795) (#30810)
authorGiteabot <teabot@gitea.io>
Thu, 2 May 2024 01:48:24 +0000 (09:48 +0800)
committerGitHub <noreply@github.com>
Thu, 2 May 2024 01:48:24 +0000 (09:48 +0800)
Backport #30795 by wxiaoguang

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
modules/markup/html.go
modules/references/references.go
modules/references/references_test.go
modules/templates/util_render_test.go

index cef643bf180570ba6199a8e7d7c4d8b12e3ff8fa..5ae0cc8755c0420dab16437dcc9170d6f23db6ed 100644 (file)
@@ -591,17 +591,16 @@ func replaceContentList(node *html.Node, i, j int, newNodes []*html.Node) {
 
 func mentionProcessor(ctx *RenderContext, node *html.Node) {
        start := 0
-       next := node.NextSibling
-       for node != nil && node != next && start < len(node.Data) {
-               // We replace only the first mention; other mentions will be addressed later
-               found, loc := references.FindFirstMentionBytes([]byte(node.Data[start:]))
+       for node != nil {
+               found, loc := references.FindFirstMentionBytes(util.UnsafeStringToBytes(node.Data[start:]))
                if !found {
-                       return
+                       node = node.NextSibling
+                       start = 0
+                       continue
                }
                loc.Start += start
                loc.End += start
                mention := node.Data[loc.Start:loc.End]
-               var teams string
                teams, ok := ctx.Metas["teams"]
                // FIXME: util.URLJoin may not be necessary here:
                // - setting.AppURL is defined to have a terminal '/' so unless mention[1:]
@@ -623,10 +622,10 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
                if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) {
                        replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention"))
                        node = node.NextSibling.NextSibling
+                       start = 0
                } else {
-                       node = node.NextSibling
+                       start = loc.End
                }
-               start = 0
        }
 }
 
index 761d6ee3d1843fc97ea59c29b8997b1d71df7094..1b656ed4cbf4481530b6e2b6344d2a39711023c6 100644 (file)
@@ -29,7 +29,7 @@ var (
        // TODO: fix invalid linking issue
 
        // mentionPattern matches all mentions in the form of "@user" or "@org/team"
-       mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_]+\/?[0-9a-zA-Z-_]+|@[0-9a-zA-Z-_][0-9a-zA-Z-_.]+\/?[0-9a-zA-Z-_.]+[0-9a-zA-Z-_])(?:\s|[:,;.?!]\s|[:,;.?!]?$|\)|\])`)
+       mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[-\w][-.\w]*?|@[-\w][-.\w]*?/[-\w][-.\w]*?)(?:\s|$|[:,;.?!](\s|$)|'|\)|\])`)
        // issueNumericPattern matches string that references to a numeric issue, e.g. #1287
        issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`)
        // issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234
index 0c329336191070f19f9549738be036381a003341..e5a0d60fe3bce2896324f252a7d556cfeb838e53 100644 (file)
@@ -392,6 +392,7 @@ func TestRegExp_mentionPattern(t *testing.T) {
                {"@gitea,", "@gitea"},
                {"@gitea;", "@gitea"},
                {"@gitea/team1;", "@gitea/team1"},
+               {"@user's idea", "@user"},
        }
        falseTestCases := []string{
                "@ 0",
@@ -412,7 +413,6 @@ func TestRegExp_mentionPattern(t *testing.T) {
 
        for _, testCase := range trueTestCases {
                found := mentionPattern.FindStringSubmatch(testCase.pat)
-               assert.Len(t, found, 2)
                assert.Equal(t, testCase.exp, found[1])
        }
        for _, testCase := range falseTestCases {
index 47c5da6485c37c7779dbab85f6c357c690259074..f493b899e393cd0fb6b1b27e6405c45661262b71 100644 (file)
@@ -207,3 +207,8 @@ func TestRenderLabels(t *testing.T) {
        expected = `/owner/repo/pulls?labels=123`
        assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
 }
+
+func TestUserMention(t *testing.T) {
+       rendered := RenderMarkdownToHtml(context.Background(), "@no-such-user @mention-user @mention-user")
+       assert.EqualValues(t, `<p>@no-such-user <a href="/mention-user" rel="nofollow">@mention-user</a> <a href="/mention-user" rel="nofollow">@mention-user</a></p>`, strings.TrimSpace(string(rendered)))
+}