Avoid emoji mismatch and allow to only enable chosen emojis (#35692)

Fix #23635
This commit is contained in:
wxiaoguang
2025-10-20 04:06:45 +08:00
committed by GitHub
parent c30d74d0f9
commit 66ee8f3553
6 changed files with 115 additions and 92 deletions

View File

@@ -5,6 +5,7 @@ package markup
import (
"strings"
"unicode"
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/setting"
@@ -66,26 +67,31 @@ func emojiShortCodeProcessor(ctx *RenderContext, node *html.Node) {
}
m[0] += start
m[1] += start
start = m[1]
alias := node.Data[m[0]:m[1]]
alias = strings.ReplaceAll(alias, ":", "")
converted := emoji.FromAlias(alias)
if converted == nil {
// check if this is a custom reaction
if _, exist := setting.UI.CustomEmojisMap[alias]; exist {
replaceContent(node, m[0], m[1], createCustomEmoji(ctx, alias))
node = node.NextSibling.NextSibling
start = 0
continue
}
var nextChar byte
if m[1] < len(node.Data) {
nextChar = node.Data[m[1]]
}
if nextChar == ':' || unicode.IsLetter(rune(nextChar)) || unicode.IsDigit(rune(nextChar)) {
continue
}
replaceContent(node, m[0], m[1], createEmoji(ctx, converted.Emoji, converted.Description))
node = node.NextSibling.NextSibling
start = 0
alias = strings.Trim(alias, ":")
converted := emoji.FromAlias(alias)
if converted != nil {
// standard emoji
replaceContent(node, m[0], m[1], createEmoji(ctx, converted.Emoji, converted.Description))
node = node.NextSibling.NextSibling
start = 0 // restart searching start since node has changed
} else if _, exist := setting.UI.CustomEmojisMap[alias]; exist {
// custom reaction
replaceContent(node, m[0], m[1], createCustomEmoji(ctx, alias))
node = node.NextSibling.NextSibling
start = 0 // restart searching start since node has changed
}
}
}

View File

@@ -357,12 +357,9 @@ func TestRender_emoji(t *testing.T) {
`<p><span class="emoji" aria-label="smiling face with sunglasses">😎</span><span class="emoji" aria-label="zany face">🤪</span><span class="emoji" aria-label="locked with key">🔐</span><span class="emoji" aria-label="money-mouth face">🤑</span><span class="emoji" aria-label="red question mark">❓</span></p>`)
// should match nothing
test(
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
`<p>2001:0db8:85a3:0000:0000:8a2e:0370:7334</p>`)
test(
":not exist:",
`<p>:not exist:</p>`)
test(":100:200", `<p>:100:200</p>`)
test("std::thread::something", `<p>std::thread::something</p>`)
test(":not exist:", `<p>:not exist:</p>`)
}
func TestRender_ShortLinks(t *testing.T) {