diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/DataMessageProcessorTest_polls.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/DataMessageProcessorTest_polls.kt index ecbd58affe..21315fe3e5 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/DataMessageProcessorTest_polls.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/DataMessageProcessorTest_polls.kt @@ -101,7 +101,7 @@ class DataMessageProcessorTest_polls { message = DataMessage(pollTerminate = DataMessage.PollTerminate(targetSentTimestamp = 100)), senderRecipient = alice, metadata = EnvelopeMetadata(alice.requireServiceId(), null, 1, false, null, harness.self.requireServiceId(), CiphertextMessage.WHISPER_TYPE), - threadRecipient = bob, + threadRecipient = Recipient.resolved(groupRecipientId), groupId = groupId, receivedTime = 200 ) @@ -310,6 +310,7 @@ class DataMessageProcessorTest_polls { envelope = MessageContentFuzzer.envelope(100), message = DataMessage(pollVote = pollVote), senderRecipient = senderRecipient, + threadRecipient = Recipient.resolved(groupRecipientId), earlyMessageCacheEntry = null ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt index 9ad6a15936..c56c6d54b1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt @@ -185,7 +185,7 @@ object DataMessageProcessor { message.groupCallUpdate != null -> handleGroupCallUpdateMessage(envelope, senderRecipient.id, groupId) message.pollCreate != null -> insertResult = handlePollCreate(context, envelope, metadata, message, senderRecipient, threadRecipient, groupId, receivedTime) message.pollTerminate != null -> insertResult = handlePollTerminate(context, envelope, metadata, message, senderRecipient, earlyMessageCacheEntry, threadRecipient, groupId, receivedTime) - message.pollVote != null -> messageId = handlePollVote(context, envelope, message, senderRecipient, earlyMessageCacheEntry) + message.pollVote != null -> messageId = handlePollVote(context, envelope, message, senderRecipient, threadRecipient, earlyMessageCacheEntry) message.pinMessage != null -> insertResult = handlePinMessage(envelope, metadata, message, senderRecipient, threadRecipient, groupId, receivedTime, earlyMessageCacheEntry) message.unpinMessage != null -> messageId = handleUnpinMessage(envelope, message, senderRecipient, threadRecipient, earlyMessageCacheEntry) message.adminDelete != null -> messageId = handleAdminRemoteDelete(context, envelope, message, senderRecipient, threadRecipient, earlyMessageCacheEntry) @@ -1152,7 +1152,7 @@ object DataMessageProcessor { handlePossibleExpirationUpdate(envelope, metadata, senderRecipient, threadRecipient, groupId, message.expireTimerDuration, message.expireTimerVersion, receivedTime) - val messageId = handlePollValidation(envelope = envelope, targetSentTimestamp = targetSentTimestamp, senderRecipient = senderRecipient, earlyMessageCacheEntry = earlyMessageCacheEntry, targetAuthor = senderRecipient) + val messageId = handlePollValidation(envelope = envelope, targetSentTimestamp = targetSentTimestamp, senderRecipient = senderRecipient, earlyMessageCacheEntry = earlyMessageCacheEntry, targetAuthor = senderRecipient, threadRecipient = threadRecipient) if (messageId == null) { return null } @@ -1191,6 +1191,7 @@ object DataMessageProcessor { envelope: Envelope, message: DataMessage, senderRecipient: Recipient, + threadRecipient: Recipient, earlyMessageCacheEntry: EarlyMessageCacheEntry? ): MessageId? { val pollVote: DataMessage.PollVote = message.pollVote!! @@ -1204,7 +1205,7 @@ object DataMessageProcessor { return null } - val messageId = handlePollValidation(envelope, targetSentTimestamp, senderRecipient, earlyMessageCacheEntry, Recipient.externalPush(targetAuthorServiceId)) + val messageId = handlePollValidation(envelope, targetSentTimestamp, senderRecipient, earlyMessageCacheEntry, Recipient.externalPush(targetAuthorServiceId), threadRecipient) if (messageId == null) { return null } @@ -1618,7 +1619,8 @@ object DataMessageProcessor { targetSentTimestamp: Long, senderRecipient: Recipient, earlyMessageCacheEntry: EarlyMessageCacheEntry?, - targetAuthor: Recipient + targetAuthor: Recipient, + threadRecipient: Recipient ): MessageId? { val targetMessage = SignalDatabase.messages.getMessageFor(targetSentTimestamp, targetAuthor.id) if (targetMessage == null) { @@ -1641,6 +1643,11 @@ object DataMessageProcessor { return null } + if (targetThreadRecipientId != threadRecipient.id) { + warn(envelope.clientTimestamp!!, "[handlePollValidation] Target poll belongs to a different conversation than the message. timestamp: $targetSentTimestamp author: ${targetAuthor.id}") + return null + } + val groupRecord = SignalDatabase.groups.getGroup(targetThreadRecipientId).orNull() if (groupRecord != null && !groupRecord.members.contains(senderRecipient.id)) { warn(envelope.clientTimestamp!!, "[handlePollValidation] Sender is not in the group. timestamp: $targetSentTimestamp author: ${targetAuthor.id}") diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt index 5b9e84822f..1157aea557 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -263,7 +263,8 @@ object SyncMessageProcessor { dataMessage.isMediaMessage -> threadId = handleSynchronizeSentMediaMessage(context, sent, envelope.clientTimestamp!!, senderRecipient) dataMessage.pollCreate != null -> threadId = handleSynchronizedPollCreate(envelope, dataMessage, sent, senderRecipient) dataMessage.pollVote != null -> { - DataMessageProcessor.handlePollVote(context, envelope, dataMessage, senderRecipient, earlyMessageCacheEntry) + val destination = getSyncMessageDestination(sent) + DataMessageProcessor.handlePollVote(context, envelope, dataMessage, senderRecipient, destination, earlyMessageCacheEntry) threadId = SignalDatabase.threads.getOrCreateThreadIdFor(getSyncMessageDestination(sent)) } dataMessage.pollTerminate != null -> threadId = handleSynchronizedPollEnd(envelope, dataMessage, sent, senderRecipient, earlyMessageCacheEntry) @@ -2060,6 +2061,13 @@ object SyncMessageProcessor { } return -1 } + + val targetThreadId = SignalDatabase.threads.getRecipientIdForThreadId(targetMessage.threadId) + if (threadId != targetMessage.threadId) { + warn(envelope.clientTimestamp!!, "Target thread does not match. $threadId $targetThreadId") + return -1 + } + val poll = SignalDatabase.polls.getPoll(targetMessage.id) if (poll == null) { warn(envelope.clientTimestamp!!, "Unable to find poll for poll termination. Dropping.")