From 5581b56cfe35bbb23d1724f973fd494a5c8ae7be Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 5 Jun 2019 18:35:41 +0100 Subject: [PATCH 1/2] Restrict reactions to a single emoji While the protocol supports more complex strings, in Riot we only want to display single emoji. Fixes https://github.com/vector-im/riot-web/issues/9916 --- src/HtmlUtils.js | 14 ++++++++++++-- src/components/views/messages/ReactionsRow.js | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index a8bbce10dc7..69a0abd90e4 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -51,6 +51,7 @@ const ZWJ_REGEX = new RegExp("\u200D|\u2003", "g"); const WHITESPACE_REGEX = new RegExp("\\s", "g"); const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, 'i'); +const SINGLE_EMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})$`, 'i'); const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/; @@ -63,10 +64,19 @@ const PERMITTED_URL_SCHEMES = ['http', 'https', 'ftp', 'mailto', 'magnet']; * need emojification. * unicodeToImage uses this function. */ -export function containsEmoji(str) { +export function mayContainEmoji(str) { return SURROGATE_PAIR_PATTERN.test(str) || SYMBOL_PATTERN.test(str); } +/** + * Returns true if the string definitely contains a single emoji. + * @param {String} str String to test + * @return {Boolean} + */ +export function isSingleEmoji(str) { + return mayContainEmoji(str) && SINGLE_EMOJI_REGEX.test(str); +} + /** * Returns the shortcode for an emoji character. * @@ -428,7 +438,7 @@ export function bodyToHtml(content, highlights, opts={}) { if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody); strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body; - bodyHasEmoji = containsEmoji(isHtmlMessage ? formattedBody : content.body); + bodyHasEmoji = mayContainEmoji(isHtmlMessage ? formattedBody : content.body); // Only generate safeBody if the message was sent as org.matrix.custom.html if (isHtmlMessage) { diff --git a/src/components/views/messages/ReactionsRow.js b/src/components/views/messages/ReactionsRow.js index b14eed88da8..51f62807a5e 100644 --- a/src/components/views/messages/ReactionsRow.js +++ b/src/components/views/messages/ReactionsRow.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import sdk from '../../../index'; import { isContentActionable } from '../../../utils/EventUtils'; +import { isSingleEmoji } from '../../../HtmlUtils'; import MatrixClientPeg from '../../../MatrixClientPeg'; export default class ReactionsRow extends React.PureComponent { @@ -103,6 +104,9 @@ export default class ReactionsRow extends React.PureComponent { const ReactionsRowButton = sdk.getComponent('messages.ReactionsRowButton'); const items = reactions.getSortedAnnotationsByKey().map(([content, events]) => { + if (!isSingleEmoji(content)) { + return null; + } const count = events.size; if (!count) { return null; From b5f85399a783e23d21232c3571ef21998552de4f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 5 Jun 2019 19:26:14 +0100 Subject: [PATCH 2/2] Rename may to might --- src/HtmlUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 69a0abd90e4..6cd06678ea9 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -64,7 +64,7 @@ const PERMITTED_URL_SCHEMES = ['http', 'https', 'ftp', 'mailto', 'magnet']; * need emojification. * unicodeToImage uses this function. */ -export function mayContainEmoji(str) { +export function mightContainEmoji(str) { return SURROGATE_PAIR_PATTERN.test(str) || SYMBOL_PATTERN.test(str); } @@ -74,7 +74,7 @@ export function mayContainEmoji(str) { * @return {Boolean} */ export function isSingleEmoji(str) { - return mayContainEmoji(str) && SINGLE_EMOJI_REGEX.test(str); + return mightContainEmoji(str) && SINGLE_EMOJI_REGEX.test(str); } /** @@ -438,7 +438,7 @@ export function bodyToHtml(content, highlights, opts={}) { if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody); strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body; - bodyHasEmoji = mayContainEmoji(isHtmlMessage ? formattedBody : content.body); + bodyHasEmoji = mightContainEmoji(isHtmlMessage ? formattedBody : content.body); // Only generate safeBody if the message was sent as org.matrix.custom.html if (isHtmlMessage) {