summaryrefslogtreecommitdiffstats
path: root/app/notification.go
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2017-04-26 11:00:38 -0400
committerCorey Hulen <corey@hulen.com>2017-04-26 08:00:38 -0700
commit8e6141152bd0978bfeb24dbfff05972f4d17fd08 (patch)
tree44074110174830b5b7604a5f38c4385bab0d01c8 /app/notification.go
parent3e73adceb58e3a28bf3653b3e12a6a861643c400 (diff)
downloadchat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.tar.gz
chat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.tar.bz2
chat-8e6141152bd0978bfeb24dbfff05972f4d17fd08.zip
PLT-3915/PLT-5550 Improve handling of Markdown while parsing mentions (#6091)
* PLT-3915 Removed ability to mention users in code blocks * PLT-3915 Added simple check for potential code blocks before using regexes * PLT-5550 Improve splitting when parsing mentions to ignore markdown characters
Diffstat (limited to 'app/notification.go')
-rw-r--r--app/notification.go30
1 files changed, 29 insertions, 1 deletions
diff --git a/app/notification.go b/app/notification.go
index 8e7e43d55..62e5e6c82 100644
--- a/app/notification.go
+++ b/app/notification.go
@@ -12,9 +12,11 @@ import (
"net/http"
"net/url"
"path/filepath"
+ "regexp"
"sort"
"strings"
"time"
+ "unicode"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/einterfaces"
@@ -660,7 +662,12 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri
}
}
- for _, word := range strings.Fields(message) {
+ message = removeCodeFromMessage(message)
+
+ for _, word := range strings.FieldsFunc(message, func(c rune) bool {
+ // Split on whitespace (as strings.Fields normally does) or on Markdown characters
+ return unicode.IsSpace(c) || c == '*' || c == '~'
+ }) {
isMention := false
if word == "@here" {
@@ -726,6 +733,27 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri
return mentioned, potentialOthersMentioned, hereMentioned, channelMentioned, allMentioned
}
+// Matches a line containing only ``` and a potential language definition, any number of lines not containing ```,
+// and then either a line containing only ``` or the end of the text
+var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*\\`\\`\\`.*$[\\s\\S]+?(^[^\\S\n]*\\`\\`\\`$|\\z)")
+
+// Matches a backquote, either some text or any number of non-empty lines, and then a final backquote
+var inlineCodePattern = regexp.MustCompile("(?m)\\`(?:.+?|.*?\n(.*?\\S.*?\n)*.*?)\\`")
+
+// Strips pre-formatted text and code blocks from a Markdown string by replacing them with whitespace
+func removeCodeFromMessage(message string) string {
+ if strings.Contains(message, "```") {
+ message = codeBlockPattern.ReplaceAllString(message, "")
+ }
+
+ // Replace with a space to prevent cases like "user`code`name" from turning into "username"
+ if strings.Contains(message, "`") {
+ message = inlineCodePattern.ReplaceAllString(message, " ")
+ }
+
+ return message
+}
+
// Given a map of user IDs to profiles, returns a list of mention
// keywords for all users in the channel.
func GetMentionKeywordsInChannel(profiles map[string]*model.User) map[string][]string {