diff --git a/epicyon.py b/epicyon.py index f1abb86d8..7cc492481 100644 --- a/epicyon.py +++ b/epicyon.py @@ -83,6 +83,7 @@ from like import sendLikeViaServer from like import sendUndoLikeViaServer from reaction import sendReactionViaServer from reaction import sendUndoReactionViaServer +from reaction import validEmojiContent from skills import sendSkillViaServer from availability import setAvailability from availability import sendAvailabilityViaServer @@ -1628,6 +1629,9 @@ if args.react: if not args.emoji: print('Specify a reaction emoji with the --emoji option') sys.exit() + if not validEmojiContent(args.emoji): + print('This is not a valid emoji') + sys.exit() if not args.password: args.password = getpass.getpass('Password: ') @@ -1698,6 +1702,9 @@ if args.undoreact: if not args.emoji: print('Specify a reaction emoji with the --emoji option') sys.exit() + if not validEmojiContent(args.emoji): + print('This is not a valid emoji') + sys.exit() if not args.password: args.password = getpass.getpass('Password: ') diff --git a/inbox.py b/inbox.py index 6469cb839..8d45aeff4 100644 --- a/inbox.py +++ b/inbox.py @@ -16,6 +16,7 @@ from linked_data_sig import verifyJsonSignature from languages import understoodPostLanguage from like import updateLikesCollection from reaction import updateReactionCollection +from reaction import validEmojiContent from utils import removeHtml from utils import fileLastModified from utils import hasObjectString @@ -1246,6 +1247,10 @@ def _receiveReaction(recentPostsCache: {}, if debug: print('DEBUG: ' + messageJson['type'] + ' content is not string') return False + if not validEmojiContent(messageJson['content']): + print('_receiveReaction: Invalid emoji reaction: "' + + messageJson['content'] + '" from ' + messageJson['actor']) + return False if not hasUsersPath(messageJson['actor']): if debug: print('DEBUG: "users" or "profile" missing from actor in ' + diff --git a/reaction.py b/reaction.py index 2aaea25f6..731fdd37c 100644 --- a/reaction.py +++ b/reaction.py @@ -8,6 +8,7 @@ __status__ = "Production" __module_group__ = "ActivityPub" import os +import re from pprint import pprint from utils import hasObjectString from utils import hasObjectStringObject @@ -35,6 +36,21 @@ from auth import createBasicAuthHeader from posts import getPersonBox +emojiRegex = re.compile(r'[\u263a-\U0001f645]') + + +def validEmojiContent(emojiContent: str) -> bool: + """Is the given emoji content valid? + """ + if not emojiContent: + return False + if len(emojiContent) > 1: + return False + if len(emojiRegex.findall(emojiContent)) == 0: + return False + return True + + def noOfReactions(postJsonObject: {}, emojiContent: str) -> int: """Returns the number of emoji reactions of a given content type on a post """ @@ -75,6 +91,9 @@ def _reaction(recentPostsCache: {}, """ if not urlPermitted(objectUrl, federationList): return None + if not validEmojiContent(emojiContent): + print('_reaction: Invalid emoji reaction: "' + emojiContent + '"') + return fullDomain = getFullDomain(domain, port) @@ -179,6 +198,10 @@ def sendReactionViaServer(baseDir: str, session, if not session: print('WARN: No session for sendReactionViaServer') return 6 + if not validEmojiContent(emojiContent): + print('sendReactionViaServer: Invalid emoji reaction: "' + + emojiContent + '"') + return 7 fromDomainFull = getFullDomain(fromDomain, fromPort) @@ -363,6 +386,10 @@ def outboxReaction(recentPostsCache: {}, return if not isinstance(messageJson['content'], str): return + if not validEmojiContent(messageJson['content']): + print('outboxReaction: Invalid emoji reaction: "' + + messageJson['content'] + '"') + return if debug: print('DEBUG: c2s reaction request arrived in outbox') diff --git a/tests.py b/tests.py index 9a7fb019f..bee2690c4 100644 --- a/tests.py +++ b/tests.py @@ -109,6 +109,7 @@ from like import likePost from like import sendLikeViaServer from reaction import reactionPost from reaction import sendReactionViaServer +from reaction import validEmojiContent from announce import announcePublic from announce import sendAnnounceViaServer from city import parseNogoString @@ -5909,6 +5910,15 @@ def _testAddCWfromLists(baseDir: str) -> None: assert postJsonObject['object']['summary'] == "Murdoch Press / Existing CW" +def _testValidEmojiContent() -> None: + print('testValidEmojiContent') + assert not validEmojiContent(None) + assert not validEmojiContent(' ') + assert not validEmojiContent('j') + assert validEmojiContent('😀') + assert validEmojiContent('😄') + + def runAllTests(): baseDir = os.getcwd() print('Running tests...') @@ -5916,6 +5926,7 @@ def runAllTests(): _translateOntology(baseDir) _testGetPriceFromString() _testFunctions() + _testValidEmojiContent() _testAddCWfromLists(baseDir) _testWordsSimilarity() _testSecondsBetweenPublished()