mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-01 06:07:37 +00:00
Only allow emojis as reactions.
This commit is contained in:
@@ -16,6 +16,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class EmojiUtil {
|
||||
|
||||
@@ -42,6 +43,8 @@ public final class EmojiUtil {
|
||||
MAX_EMOJI_LENGTH = max;
|
||||
}
|
||||
|
||||
private static final Pattern EMOJI_PATTERN = Pattern.compile("^(?:(?:[\u00a9\u00ae\u203c\u2049\u2122\u2139\u2194-\u2199\u21a9-\u21aa\u231a-\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\u24c2\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614-\u2615\u2618\u261d\u2620\u2622-\u2623\u2626\u262a\u262e-\u262f\u2638-\u263a\u2648-\u2653\u2660\u2663\u2665-\u2666\u2668\u267b\u267f\u2692-\u2694\u2696-\u2697\u2699\u269b-\u269c\u26a0-\u26a1\u26aa-\u26ab\u26b0-\u26b1\u26bd-\u26be\u26c4-\u26c5\u26c8\u26ce-\u26cf\u26d1\u26d3-\u26d4\u26e9-\u26ea\u26f0-\u26f5\u26f7-\u26fa\u26fd\u2702\u2705\u2708-\u270d\u270f\u2712\u2714\u2716\u271d\u2721\u2728\u2733-\u2734\u2744\u2747\u274c\u274e\u2753-\u2755\u2757\u2763-\u2764\u2795-\u2797\u27a1\u27b0\u27bf\u2934-\u2935\u2b05-\u2b07\u2b1b-\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299\ud83c\udc04\ud83c\udccf\ud83c\udd70-\ud83c\udd71\ud83c\udd7e-\ud83c\udd7f\ud83c\udd8e\ud83c\udd91-\ud83c\udd9a\ud83c\ude01-\ud83c\ude02\ud83c\ude1a\ud83c\ude2f\ud83c\ude32-\ud83c\ude3a\ud83c\ude50-\ud83c\ude51\u200d\ud83c\udf00-\ud83d\uddff\ud83d\ude00-\ud83d\ude4f\ud83d\ude80-\ud83d\udeff\ud83e\udd00-\ud83e\uddff\udb40\udc20-\udb40\udc7f]|\u200d[\u2640\u2642]|[\ud83c\udde6-\ud83c\uddff]{2}|.[\u20e0\u20e3\ufe0f]+)+)+$");
|
||||
|
||||
private EmojiUtil() {}
|
||||
|
||||
public static List<EmojiPageModel> getDisplayPages() {
|
||||
@@ -90,4 +93,25 @@ public final class EmojiUtil {
|
||||
return EmojiProvider.getInstance(context).getEmojiDrawable(emoji);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the text is likely a single, valid emoji. Otherwise false.
|
||||
*
|
||||
* We do a two-tier check: first using our own knowledge of emojis (which could be incomplete),
|
||||
* followed by a more wide check for all of the valid emoji unicode ranges (which could lead to
|
||||
* some false positives). YMMV.
|
||||
*/
|
||||
public static boolean isEmoji(@NonNull Context context, @Nullable String text) {
|
||||
if (Util.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StringUtil.getGraphemeCount(text) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EmojiParser.CandidateList candidates = EmojiProvider.getInstance(context).getCandidates(text);
|
||||
|
||||
return (candidates != null && candidates.size() > 0) || EMOJI_PATTERN.matcher(text).matches();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.attachments.PointerAttachment;
|
||||
import org.thoughtcrime.securesms.attachments.TombstoneAttachment;
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment;
|
||||
import org.thoughtcrime.securesms.components.emoji.Emoji;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiUtil;
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.contactshare.ContactModelMapper;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
@@ -690,6 +692,11 @@ public final class MessageContentProcessor {
|
||||
private void handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
||||
SignalServiceDataMessage.Reaction reaction = message.getReaction().get();
|
||||
|
||||
if (!EmojiUtil.isEmoji(context, reaction.getEmoji())) {
|
||||
Log.w(TAG, "Reaction text is not a valid emoji! Ignoring the message.");
|
||||
return;
|
||||
}
|
||||
|
||||
Recipient targetAuthor = Recipient.externalPush(context, reaction.getTargetAuthor());
|
||||
MessageRecord targetMessage = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.text.BidiFormatter;
|
||||
|
||||
import org.signal.core.util.BreakIteratorCompat;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -265,4 +267,13 @@ public final class StringUtil {
|
||||
int end = (maxChars - 1) - start;
|
||||
return text.subSequence(0, start) + "…" + text.subSequence(text.length() - end, text.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of graphemes in the provided string.
|
||||
*/
|
||||
public static int getGraphemeCount(@NonNull CharSequence text) {
|
||||
BreakIteratorCompat iterator = BreakIteratorCompat.getInstance();
|
||||
iterator.setText(text);
|
||||
return iterator.countBreaks();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user