Skip to content

Commit ce08a9f

Browse files
authored
Fix markdown rendering when mentioning users (#30795)
1 parent 6f7cd94 commit ce08a9f

File tree

4 files changed

+14
-10
lines changed

4 files changed

+14
-10
lines changed

modules/markup/html.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -591,17 +591,16 @@ func replaceContentList(node *html.Node, i, j int, newNodes []*html.Node) {
591591

592592
func mentionProcessor(ctx *RenderContext, node *html.Node) {
593593
start := 0
594-
next := node.NextSibling
595-
for node != nil && node != next && start < len(node.Data) {
596-
// We replace only the first mention; other mentions will be addressed later
597-
found, loc := references.FindFirstMentionBytes([]byte(node.Data[start:]))
594+
for node != nil {
595+
found, loc := references.FindFirstMentionBytes(util.UnsafeStringToBytes(node.Data[start:]))
598596
if !found {
599-
return
597+
node = node.NextSibling
598+
start = 0
599+
continue
600600
}
601601
loc.Start += start
602602
loc.End += start
603603
mention := node.Data[loc.Start:loc.End]
604-
var teams string
605604
teams, ok := ctx.Metas["teams"]
606605
// FIXME: util.URLJoin may not be necessary here:
607606
// - setting.AppURL is defined to have a terminal '/' so unless mention[1:]
@@ -623,10 +622,10 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
623622
if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) {
624623
replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention"))
625624
node = node.NextSibling.NextSibling
625+
start = 0
626626
} else {
627-
node = node.NextSibling
627+
start = loc.End
628628
}
629-
start = 0
630629
}
631630
}
632631

modules/references/references.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var (
2929
// TODO: fix invalid linking issue
3030

3131
// mentionPattern matches all mentions in the form of "@user" or "@org/team"
32-
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|[:,;.?!]?$|\)|\])`)
32+
mentionPattern = regexp.MustCompile(`(?:\s|^|\(|\[)(@[-\w][-.\w]*?|@[-\w][-.\w]*?/[-\w][-.\w]*?)(?:\s|$|[:,;.?!](\s|$)|'|\)|\])`)
3333
// issueNumericPattern matches string that references to a numeric issue, e.g. #1287
3434
issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`)
3535
// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234

modules/references/references_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ func TestRegExp_mentionPattern(t *testing.T) {
392392
{"@gitea,", "@gitea"},
393393
{"@gitea;", "@gitea"},
394394
{"@gitea/team1;", "@gitea/team1"},
395+
{"@user's idea", "@user"},
395396
}
396397
falseTestCases := []string{
397398
"@ 0",
@@ -412,7 +413,6 @@ func TestRegExp_mentionPattern(t *testing.T) {
412413

413414
for _, testCase := range trueTestCases {
414415
found := mentionPattern.FindStringSubmatch(testCase.pat)
415-
assert.Len(t, found, 2)
416416
assert.Equal(t, testCase.exp, found[1])
417417
}
418418
for _, testCase := range falseTestCases {

modules/templates/util_render_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,8 @@ func TestRenderLabels(t *testing.T) {
207207
expected = `/owner/repo/pulls?labels=123`
208208
assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected)
209209
}
210+
211+
func TestUserMention(t *testing.T) {
212+
rendered := RenderMarkdownToHtml(context.Background(), "@no-such-user @mention-user @mention-user")
213+
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)))
214+
}

0 commit comments

Comments
 (0)