mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-21 10:17:56 +00:00
Add various backup fixes for polls.
This commit is contained in:
committed by
jeffrey-signal
parent
3f5a4ebf7b
commit
47201f4955
@@ -123,6 +123,14 @@ object ExportSkips {
|
||||
return log(sentTimestamp, "Poll terminate update was empty.")
|
||||
}
|
||||
|
||||
fun invalidPollQuestion(sentTimestamp: Long): String {
|
||||
return log(sentTimestamp, "Poll question was invalid.")
|
||||
}
|
||||
|
||||
fun invalidPollOption(sentTimestamp: Long): String {
|
||||
return log(sentTimestamp, "Poll option was invalid.")
|
||||
}
|
||||
|
||||
fun individualChatUpdateInWrongTypeOfChat(sentTimestamp: Long): String {
|
||||
return log(sentTimestamp, "A chat update that only makes sense for individual chats was found in a different kind of chat.")
|
||||
}
|
||||
|
||||
@@ -117,6 +117,8 @@ private val TAG = Log.tag(ChatItemArchiveExporter::class.java)
|
||||
private val MAX_INLINED_BODY_SIZE = 128.kibiBytes.bytes.toInt()
|
||||
private val MAX_INLINED_BODY_SIZE_WITH_LONG_ATTACHMENT_POINTER = 2.kibiBytes.bytes.toInt()
|
||||
private val MAX_INLINED_QUOTE_BODY_SIZE = 2.kibiBytes.bytes.toInt()
|
||||
private const val MAX_POLL_CHARACTER_LENGTH = 100
|
||||
private const val MAX_POLL_OPTIONS = 10
|
||||
|
||||
/**
|
||||
* An iterator for chat items with a clever performance twist: rather than do the extra queries one at a time (for reactions,
|
||||
@@ -386,7 +388,15 @@ class ChatItemArchiveExporter(
|
||||
|
||||
extraData.pollsById[record.id] != null -> {
|
||||
val poll = extraData.pollsById[record.id]!!
|
||||
builder.poll = poll.toRemotePollMessage()
|
||||
if (poll.question.isEmpty() || poll.question.length > MAX_POLL_CHARACTER_LENGTH) {
|
||||
Log.w(TAG, ExportSkips.invalidPollQuestion(record.dateSent))
|
||||
continue
|
||||
}
|
||||
if (poll.pollOptions.isEmpty() || poll.pollOptions.size > MAX_POLL_OPTIONS || poll.pollOptions.any { it.text.isEmpty() || it.text.length > MAX_POLL_CHARACTER_LENGTH }) {
|
||||
Log.w(TAG, ExportSkips.invalidPollOption(record.dateSent))
|
||||
continue
|
||||
}
|
||||
builder.poll = poll.toRemotePollMessage(reactionRecords = extraData.reactionsById[record.id])
|
||||
transformTimer.emit("poll")
|
||||
}
|
||||
|
||||
@@ -492,7 +502,7 @@ class ChatItemArchiveExporter(
|
||||
|
||||
val pollsFuture = executor.submitTyped {
|
||||
extraDataTimer.timeEvent("polls") {
|
||||
db.pollTable.getPollsForMessages(messageIds)
|
||||
db.pollTable.getPollsForMessages(messageIds = messageIds, includePending = false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,7 +1177,7 @@ private fun BackupMessageRecord.toRemoteGiftBadgeUpdate(): BackupGiftBadge? {
|
||||
)
|
||||
}
|
||||
|
||||
private fun PollRecord.toRemotePollMessage(): Poll {
|
||||
private fun PollRecord.toRemotePollMessage(reactionRecords: List<ReactionRecord>?): Poll {
|
||||
return Poll(
|
||||
question = this.question,
|
||||
allowMultiple = this.allowMultipleVotes,
|
||||
@@ -1182,7 +1192,8 @@ private fun PollRecord.toRemotePollMessage(): Poll {
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
reactions = reactionRecords?.toRemote() ?: emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -693,6 +693,7 @@ class ChatItemArchiveImporter(
|
||||
this.stickerMessage != null -> this.stickerMessage.reactions
|
||||
this.viewOnceMessage != null -> this.viewOnceMessage.reactions
|
||||
this.directStoryReplyMessage != null -> this.directStoryReplyMessage.reactions
|
||||
this.poll != null -> this.poll.reactions
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +607,7 @@ class PollTables(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
/**
|
||||
* Maps message ids to its associated poll (if it exists)
|
||||
*/
|
||||
fun getPollsForMessages(messageIds: Collection<Long>): Map<Long, PollRecord> {
|
||||
fun getPollsForMessages(messageIds: Collection<Long>, includePending: Boolean = true): Map<Long, PollRecord> {
|
||||
if (messageIds.isEmpty() || !Recipient.isSelfSet) {
|
||||
return emptyMap()
|
||||
}
|
||||
@@ -625,9 +625,9 @@ class PollTables(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
val (pendingAdds, pendingRemoves) = getPendingVotes(pollId)
|
||||
val pollOptions = getPollOptions(pollId).map { option ->
|
||||
val voters = pollVotes[option.key] ?: emptyList()
|
||||
val voteState = if (pendingAdds.contains(option.key)) {
|
||||
val voteState = if (includePending && pendingAdds.contains(option.key)) {
|
||||
VoteState.PENDING_ADD
|
||||
} else if (pendingRemoves.contains(option.key)) {
|
||||
} else if (includePending && pendingRemoves.contains(option.key)) {
|
||||
VoteState.PENDING_REMOVE
|
||||
} else if (voters.any { it.id == self }) {
|
||||
VoteState.ADDED
|
||||
|
||||
@@ -120,6 +120,8 @@ import kotlin.time.Duration.Companion.seconds
|
||||
object DataMessageProcessor {
|
||||
|
||||
private const val BODY_RANGE_PROCESSING_LIMIT = 250
|
||||
private const val POLL_CHARACTER_LIMIT = 100
|
||||
private const val POLL_OPTIONS_LIMIT = 10
|
||||
|
||||
fun process(
|
||||
context: Context,
|
||||
@@ -1079,6 +1081,16 @@ object DataMessageProcessor {
|
||||
return null
|
||||
}
|
||||
|
||||
if (poll.question == null || poll.question!!.isEmpty() || poll.question!!.length > POLL_CHARACTER_LIMIT) {
|
||||
warn(envelope.timestamp!!, "[handlePollCreate] Poll question is invalid.")
|
||||
return null
|
||||
}
|
||||
|
||||
if (poll.options.isEmpty() || poll.options.size > POLL_OPTIONS_LIMIT || poll.options.any { it.isEmpty() || it.length > POLL_CHARACTER_LIMIT }) {
|
||||
warn(envelope.timestamp!!, "[handlePollCreate] Poll option is invalid.")
|
||||
return null
|
||||
}
|
||||
|
||||
val pollMessage = IncomingMessage(
|
||||
type = MessageType.NORMAL,
|
||||
from = senderRecipient.id,
|
||||
|
||||
Reference in New Issue
Block a user