mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Fix markdown rendering when mentioning users (#30795)
This commit is contained in:
		| @@ -591,17 +591,16 @@ func replaceContentList(node *html.Node, i, j int, newNodes []*html.Node) { | |||||||
|  |  | ||||||
| func mentionProcessor(ctx *RenderContext, node *html.Node) { | func mentionProcessor(ctx *RenderContext, node *html.Node) { | ||||||
| 	start := 0 | 	start := 0 | ||||||
| 	next := node.NextSibling | 	for node != nil { | ||||||
| 	for node != nil && node != next && start < len(node.Data) { | 		found, loc := references.FindFirstMentionBytes(util.UnsafeStringToBytes(node.Data[start:])) | ||||||
| 		// We replace only the first mention; other mentions will be addressed later |  | ||||||
| 		found, loc := references.FindFirstMentionBytes([]byte(node.Data[start:])) |  | ||||||
| 		if !found { | 		if !found { | ||||||
| 			return | 			node = node.NextSibling | ||||||
|  | 			start = 0 | ||||||
|  | 			continue | ||||||
| 		} | 		} | ||||||
| 		loc.Start += start | 		loc.Start += start | ||||||
| 		loc.End += start | 		loc.End += start | ||||||
| 		mention := node.Data[loc.Start:loc.End] | 		mention := node.Data[loc.Start:loc.End] | ||||||
| 		var teams string |  | ||||||
| 		teams, ok := ctx.Metas["teams"] | 		teams, ok := ctx.Metas["teams"] | ||||||
| 		// FIXME: util.URLJoin may not be necessary here: | 		// FIXME: util.URLJoin may not be necessary here: | ||||||
| 		// - setting.AppURL is defined to have a terminal '/' so unless mention[1:] | 		// - 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) { | 		if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) { | ||||||
| 			replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention")) | 			replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention")) | ||||||
| 			node = node.NextSibling.NextSibling | 			node = node.NextSibling.NextSibling | ||||||
|  | 			start = 0 | ||||||
| 		} else { | 		} else { | ||||||
| 			node = node.NextSibling | 			start = loc.End | ||||||
| 		} | 		} | ||||||
| 		start = 0 |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ var ( | |||||||
| 	// TODO: fix invalid linking issue | 	// TODO: fix invalid linking issue | ||||||
|  |  | ||||||
| 	// mentionPattern matches all mentions in the form of "@user" or "@org/team" | 	// 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 matches string that references to a numeric issue, e.g. #1287 | ||||||
| 	issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`) | 	issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`) | ||||||
| 	// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234 | 	// issueAlphanumericPattern matches string that references to an alphanumeric issue, e.g. ABC-1234 | ||||||
|   | |||||||
| @@ -392,6 +392,7 @@ func TestRegExp_mentionPattern(t *testing.T) { | |||||||
| 		{"@gitea,", "@gitea"}, | 		{"@gitea,", "@gitea"}, | ||||||
| 		{"@gitea;", "@gitea"}, | 		{"@gitea;", "@gitea"}, | ||||||
| 		{"@gitea/team1;", "@gitea/team1"}, | 		{"@gitea/team1;", "@gitea/team1"}, | ||||||
|  | 		{"@user's idea", "@user"}, | ||||||
| 	} | 	} | ||||||
| 	falseTestCases := []string{ | 	falseTestCases := []string{ | ||||||
| 		"@ 0", | 		"@ 0", | ||||||
| @@ -412,7 +413,6 @@ func TestRegExp_mentionPattern(t *testing.T) { | |||||||
|  |  | ||||||
| 	for _, testCase := range trueTestCases { | 	for _, testCase := range trueTestCases { | ||||||
| 		found := mentionPattern.FindStringSubmatch(testCase.pat) | 		found := mentionPattern.FindStringSubmatch(testCase.pat) | ||||||
| 		assert.Len(t, found, 2) |  | ||||||
| 		assert.Equal(t, testCase.exp, found[1]) | 		assert.Equal(t, testCase.exp, found[1]) | ||||||
| 	} | 	} | ||||||
| 	for _, testCase := range falseTestCases { | 	for _, testCase := range falseTestCases { | ||||||
|   | |||||||
| @@ -207,3 +207,8 @@ func TestRenderLabels(t *testing.T) { | |||||||
| 	expected = `/owner/repo/pulls?labels=123` | 	expected = `/owner/repo/pulls?labels=123` | ||||||
| 	assert.Contains(t, RenderLabels(ctx, locale, []*issues.Label{label}, "/owner/repo", issue), expected) | 	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))) | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user