Ensure that backup timestamps are within a certain range.
This commit is contained in:
parent
7042ce8c5c
commit
b983a56dd2
6 changed files with 29 additions and 20 deletions
|
@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.backup.v2.database
|
|||
import android.database.Cursor
|
||||
import org.signal.core.util.requireLong
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.AdHocCall
|
||||
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
|
||||
import org.thoughtcrime.securesms.database.CallTable
|
||||
import java.io.Closeable
|
||||
|
||||
|
@ -31,7 +32,7 @@ class AdHocCallArchiveExporter(private val cursor: Cursor) : Iterator<AdHocCall>
|
|||
callId = callId,
|
||||
recipientId = cursor.requireLong(CallTable.PEER),
|
||||
state = AdHocCall.State.GENERIC,
|
||||
callTimestamp = cursor.requireLong(CallTable.TIMESTAMP)
|
||||
callTimestamp = cursor.requireLong(CallTable.TIMESTAMP).clampToValidBackupRange()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.signal.core.util.requireInt
|
|||
import org.signal.core.util.requireLong
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.Chat
|
||||
import org.thoughtcrime.securesms.backup.v2.util.ChatStyleConverter
|
||||
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
|
@ -57,7 +58,7 @@ class ChatArchiveExporter(private val cursor: Cursor, private val db: SignalData
|
|||
pinnedOrder = cursor.requireInt(ThreadTable.PINNED),
|
||||
expirationTimerMs = cursor.requireLong(RecipientTable.MESSAGE_EXPIRATION_TIME).seconds.inWholeMilliseconds.takeIf { it > 0 },
|
||||
expireTimerVersion = cursor.requireInt(RecipientTable.MESSAGE_EXPIRATION_TIME_VERSION),
|
||||
muteUntilMs = cursor.requireLong(RecipientTable.MUTE_UNTIL).takeIf { it > 0 },
|
||||
muteUntilMs = cursor.requireLong(RecipientTable.MUTE_UNTIL).takeIf { it > 0 }?.clampToValidBackupRange(),
|
||||
markedUnread = ThreadTable.ReadStatus.deserialize(cursor.requireInt(ThreadTable.READ)) == ThreadTable.ReadStatus.FORCED_UNREAD,
|
||||
dontNotifyForMentionsIfMuted = RecipientTable.MentionSetting.DO_NOT_NOTIFY.id == cursor.requireInt(RecipientTable.MENTION_SETTING),
|
||||
style = ChatStyleConverter.constructRemoteChatStyle(
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.thoughtcrime.securesms.backup.v2.proto.StickerMessage
|
|||
import org.thoughtcrime.securesms.backup.v2.proto.Text
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.ThreadMergeChatUpdate
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.ViewOnceMessage
|
||||
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
|
||||
import org.thoughtcrime.securesms.backup.v2.util.toRemoteFilePointer
|
||||
import org.thoughtcrime.securesms.contactshare.Contact
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
|
@ -431,7 +432,7 @@ private fun BackupMessageRecord.toBasicChatItemBuilder(selfRecipientId: Recipien
|
|||
val builder = ChatItem.Builder().apply {
|
||||
chatId = record.threadId
|
||||
authorId = fromRecipientId
|
||||
dateSent = record.dateSent
|
||||
dateSent = record.dateSent.clampToValidBackupRange()
|
||||
expireStartDate = record.expireStarted.takeIf { it > 0 }
|
||||
expiresInMs = record.expiresIn.takeIf { it > 0 }
|
||||
revisions = emptyList()
|
||||
|
@ -603,8 +604,8 @@ private fun CallTable.Call.toRemoteCallUpdate(db: SignalDatabase, messageRecord:
|
|||
},
|
||||
ringerRecipientId = this.ringerRecipient?.toLong(),
|
||||
startedCallRecipientId = ACI.parseOrNull(groupCallUpdateDetails.startedCallUuid)?.let { db.recipientTable.getByAci(it).getOrNull()?.toLong() },
|
||||
startedCallTimestamp = this.timestamp,
|
||||
endedCallTimestamp = groupCallUpdateDetails.endedCallTimestamp,
|
||||
startedCallTimestamp = this.timestamp.clampToValidBackupRange(),
|
||||
endedCallTimestamp = groupCallUpdateDetails.endedCallTimestamp.clampToValidBackupRange(),
|
||||
read = messageRecord.read
|
||||
)
|
||||
)
|
||||
|
@ -634,7 +635,7 @@ private fun CallTable.Call.toRemoteCallUpdate(db: SignalDatabase, messageRecord:
|
|||
return null
|
||||
}
|
||||
},
|
||||
startedCallTimestamp = this.timestamp,
|
||||
startedCallTimestamp = this.timestamp.clampToValidBackupRange(),
|
||||
read = messageRecord.read
|
||||
)
|
||||
)
|
||||
|
@ -720,7 +721,7 @@ private fun BackupMessageRecord.toRemoteLinkPreviews(attachments: List<DatabaseA
|
|||
val attachment = attachmentIdMap[preview.attachmentId]
|
||||
|
||||
if (attachment != null) {
|
||||
previews += LinkPreview(preview.url, preview.title, preview.description, preview.date, attachment)
|
||||
previews += LinkPreview(preview.url, preview.title, preview.description, preview.date.clampToValidBackupRange(), attachment)
|
||||
} else {
|
||||
previews += preview
|
||||
}
|
||||
|
@ -745,7 +746,7 @@ private fun LinkPreview.toRemoteLinkPreview(mediaArchiveEnabled: Boolean): org.t
|
|||
title = title.nullIfEmpty(),
|
||||
image = (thumbnail.orNull() as? DatabaseAttachment)?.toRemoteMessageAttachment(mediaArchiveEnabled)?.pointer,
|
||||
description = description.nullIfEmpty(),
|
||||
date = date
|
||||
date = date.clampToValidBackupRange()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -884,7 +885,7 @@ private fun BackupMessageRecord.toRemoteQuote(mediaArchiveEnabled: Boolean, atta
|
|||
}
|
||||
|
||||
return Quote(
|
||||
targetSentTimestamp = this.quoteTargetSentTimestamp.takeIf { !this.quoteMissing && it != MessageTable.QUOTE_TARGET_MISSING_ID },
|
||||
targetSentTimestamp = this.quoteTargetSentTimestamp.takeIf { !this.quoteMissing && it != MessageTable.QUOTE_TARGET_MISSING_ID }?.clampToValidBackupRange(),
|
||||
authorId = this.quoteAuthor,
|
||||
text = this.quoteBody?.let { body ->
|
||||
Text(
|
||||
|
@ -981,9 +982,9 @@ private fun PaymentTable.PaymentTransaction.toRemoteTransactionDetails(): Paymen
|
|||
return PaymentNotification.TransactionDetails(
|
||||
transaction = PaymentNotification.TransactionDetails.Transaction(
|
||||
status = this.state.toRemote(),
|
||||
timestamp = this.timestamp,
|
||||
timestamp = this.timestamp.clampToValidBackupRange(),
|
||||
blockIndex = this.blockIndex,
|
||||
blockTimestamp = this.blockTimestamp,
|
||||
blockTimestamp = this.blockTimestamp.clampToValidBackupRange(),
|
||||
mobileCoinIdentification = this.paymentMetaData.mobileCoinTxoIdentification?.let {
|
||||
PaymentNotification.TransactionDetails.MobileCoinTxoIdentification(
|
||||
publicKey = it.publicKey.takeIf { this.direction.isReceived } ?: emptyList(),
|
||||
|
@ -1065,7 +1066,7 @@ private fun List<ReactionRecord>?.toRemote(): List<Reaction> {
|
|||
Reaction(
|
||||
emoji = it.emoji,
|
||||
authorId = it.author.toLong(),
|
||||
sentTimestamp = it.dateSent,
|
||||
sentTimestamp = it.dateSent.clampToValidBackupRange(),
|
||||
sortOrder = it.dateReceived
|
||||
)
|
||||
} ?: emptyList()
|
||||
|
@ -1298,9 +1299,9 @@ private fun Cursor.toBackupMessageRecord(pastIds: Set<Long>, backupStartTime: Lo
|
|||
|
||||
return BackupMessageRecord(
|
||||
id = id,
|
||||
dateSent = this.requireLong(MessageTable.DATE_SENT),
|
||||
dateReceived = this.requireLong(MessageTable.DATE_RECEIVED),
|
||||
dateServer = this.requireLong(MessageTable.DATE_SERVER),
|
||||
dateSent = this.requireLong(MessageTable.DATE_SENT).clampToValidBackupRange(),
|
||||
dateReceived = this.requireLong(MessageTable.DATE_RECEIVED).clampToValidBackupRange(),
|
||||
dateServer = this.requireLong(MessageTable.DATE_SERVER).clampToValidBackupRange(),
|
||||
type = this.requireLong(MessageTable.TYPE),
|
||||
threadId = this.requireLong(MessageTable.THREAD_ID),
|
||||
body = this.requireString(MessageTable.BODY),
|
||||
|
@ -1313,7 +1314,7 @@ private fun Cursor.toBackupMessageRecord(pastIds: Set<Long>, backupStartTime: Lo
|
|||
sealedSender = this.requireBoolean(MessageTable.UNIDENTIFIED),
|
||||
linkPreview = this.requireString(MessageTable.LINK_PREVIEWS),
|
||||
sharedContacts = this.requireString(MessageTable.SHARED_CONTACTS),
|
||||
quoteTargetSentTimestamp = this.requireLong(MessageTable.QUOTE_ID),
|
||||
quoteTargetSentTimestamp = this.requireLong(MessageTable.QUOTE_ID).clampToValidBackupRange(),
|
||||
quoteAuthor = this.requireLong(MessageTable.QUOTE_AUTHOR),
|
||||
quoteBody = this.requireString(MessageTable.QUOTE_BODY),
|
||||
quoteMissing = this.requireBoolean(MessageTable.QUOTE_MISSING),
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.signal.core.util.requireString
|
|||
import org.thoughtcrime.securesms.backup.v2.ArchiveRecipient
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.Contact
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.Self
|
||||
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
|
||||
import org.thoughtcrime.securesms.database.IdentityTable
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.RecipientTableCursorUtil
|
||||
|
@ -80,7 +81,7 @@ class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Lon
|
|||
if (registeredState == RecipientTable.RegisteredState.REGISTERED) {
|
||||
contactBuilder.registered = Contact.Registered()
|
||||
} else {
|
||||
contactBuilder.notRegistered = Contact.NotRegistered(unregisteredTimestamp = cursor.requireLong(RecipientTable.UNREGISTERED_TIMESTAMP))
|
||||
contactBuilder.notRegistered = Contact.NotRegistered(unregisteredTimestamp = cursor.requireLong(RecipientTable.UNREGISTERED_TIMESTAMP).clampToValidBackupRange())
|
||||
}
|
||||
|
||||
return ArchiveRecipient(
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.backup.v2.ArchiveRecipient
|
|||
import org.thoughtcrime.securesms.backup.v2.database.getMembersForBackup
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.DistributionList
|
||||
import org.thoughtcrime.securesms.backup.v2.proto.DistributionListItem
|
||||
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
|
||||
import org.thoughtcrime.securesms.database.DistributionListTables
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListId
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListPrivacyMode
|
||||
|
@ -49,7 +50,7 @@ class DistributionListArchiveExporter(
|
|||
allowsReplies = cursor.requireBoolean(DistributionListTables.ListTable.ALLOWS_REPLIES),
|
||||
rawMembers = distributionListTables.getRawMembers(id, privacyMode),
|
||||
members = distributionListTables.getMembersForBackup(id),
|
||||
deletedAtTimestamp = cursor.requireLong(DistributionListTables.ListTable.DELETION_TIMESTAMP),
|
||||
deletedAtTimestamp = cursor.requireLong(DistributionListTables.ListTable.DELETION_TIMESTAMP).clampToValidBackupRange(),
|
||||
isUnknown = cursor.requireBoolean(DistributionListTables.ListTable.IS_UNKNOWN),
|
||||
privacyMode = privacyMode
|
||||
)
|
||||
|
|
|
@ -62,7 +62,7 @@ fun FilePointer?.toLocalAttachment(
|
|||
isGif = gif,
|
||||
caption = Optional.ofNullable(this.caption),
|
||||
blurHash = Optional.ofNullable(this.blurHash),
|
||||
uploadTimestamp = this.attachmentLocator.uploadTimestamp ?: 0,
|
||||
uploadTimestamp = this.attachmentLocator.uploadTimestamp?.clampToValidBackupRange() ?: 0,
|
||||
uuid = UuidUtil.fromByteStringOrNull(uuid)
|
||||
)
|
||||
return PointerAttachment.forPointer(
|
||||
|
@ -165,10 +165,14 @@ fun DatabaseAttachment.toRemoteFilePointer(mediaArchiveEnabled: Boolean, content
|
|||
builder.attachmentLocator = FilePointer.AttachmentLocator(
|
||||
cdnKey = this.remoteLocation,
|
||||
cdnNumber = this.cdn.cdnNumber,
|
||||
uploadTimestamp = this.uploadTimestamp.takeIf { it > 0 },
|
||||
uploadTimestamp = this.uploadTimestamp.takeIf { it > 0 }?.clampToValidBackupRange(),
|
||||
key = Base64.decode(remoteKey).toByteString(),
|
||||
size = this.size.toInt(),
|
||||
digest = this.remoteDigest.toByteString()
|
||||
)
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
fun Long.clampToValidBackupRange(): Long {
|
||||
return this.coerceIn(0, 8640000000000000)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue