diff --git a/app/notification.go b/app/notification.go index 5744e2d458..d7d8d94108 100644 --- a/app/notification.go +++ b/app/notification.go @@ -8,6 +8,7 @@ import ( "sort" "strings" "unicode" + "unicode/utf8" "github.com/mattermost/mattermost-server/mlog" "github.com/mattermost/mattermost-server/model" @@ -468,6 +469,14 @@ func GetExplicitMentions(post *model.Post, keywords map[string][]string) *Explic return isMention } + + var multibyteKeywords []string + for keyword := range keywords { + if len(keyword) != utf8.RuneCountInString(keyword) { + multibyteKeywords = append(multibyteKeywords, keyword) + } + } + processText := func(text string) { for _, word := range strings.FieldsFunc(text, func(c rune) bool { // Split on any whitespace or punctuation that can't be part of an at mention or emoji pattern @@ -516,6 +525,17 @@ func GetExplicitMentions(post *model.Post, keywords map[string][]string) *Explic } } } + + // If word contains a multibyte character, check if it contains a multibyte keyword + if len(word) != utf8.RuneCountInString(word) { + for _, key := range multibyteKeywords { + if strings.Contains(word, key) { + if ids, match := keywords[key]; match { + addMentionedUsers(ids) + } + } + } + } } } diff --git a/app/notification_test.go b/app/notification_test.go index f7c583616b..2438112ad0 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -474,6 +474,51 @@ func TestGetExplicitMentions(t *testing.T) { ChannelMentioned: true, }, }, + "MultibyteCharacter": { + Message: "My name is 萌", + Keywords: map[string][]string{"萌": {id1}}, + Expected: &ExplicitMentions{ + MentionedUserIds: map[string]bool{ + id1: true, + }, + }, + }, + "MultibyteCharacterAtBeginningOfSentence": { + Message: "이메일을 보내다.", + Keywords: map[string][]string{"이메일": {id1}}, + Expected: &ExplicitMentions{ + MentionedUserIds: map[string]bool{ + id1: true, + }, + }, + }, + "MultibyteCharacterInPartOfSentence": { + Message: "我爱吃番茄炒饭", + Keywords: map[string][]string{"番茄": {id1}}, + Expected: &ExplicitMentions{ + MentionedUserIds: map[string]bool{ + id1: true, + }, + }, + }, + "MultibyteCharacterAtEndOfSentence": { + Message: "こんにちは、世界", + Keywords: map[string][]string{"世界": {id1}}, + Expected: &ExplicitMentions{ + MentionedUserIds: map[string]bool{ + id1: true, + }, + }, + }, + "MultibyteCharacterTwiceInSentence": { + Message: "石橋さんが石橋を渡る", + Keywords: map[string][]string{"石橋": {id1}}, + Expected: &ExplicitMentions{ + MentionedUserIds: map[string]bool{ + id1: true, + }, + }, + }, // The following tests cover cases where the message mentions @user.name, so we shouldn't assume that // the user might be intending to mention some @user that isn't in the channel.