From 0695a0172554276d94c566e9e864aa2eae0f56e8 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 17 Jan 2025 15:51:24 -0500 Subject: [PATCH] Improve backup validation of empty items. --- .../securesms/backup/v2/ArchiveErrorCases.kt | 6 +++- .../v2/exporters/ChatArchiveExporter.kt | 1 - .../v2/exporters/ChatItemArchiveExporter.kt | 34 +++++++++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt index 7a04bed8da..07fb7777bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt @@ -12,7 +12,11 @@ import org.thoughtcrime.securesms.database.CallTable */ object ExportSkips { fun emptyChatItem(sentTimestamp: Long): String { - return log(sentTimestamp, "Completely empty ChatItem (no body or attachments).") + return log(sentTimestamp, "Completely empty ChatItem (no inner item is set).") + } + + fun emptyStandardMessage(sentTimestamp: Long): String { + return log(sentTimestamp, "Completely empty StandardMessage (no body or attachments).") } fun invalidLongTextChatItem(sentTimestamp: Long): String { diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatArchiveExporter.kt index 0100ff57ce..2e2599006c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatArchiveExporter.kt @@ -13,7 +13,6 @@ 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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt index 3e6910bb38..4075879326 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt @@ -297,11 +297,6 @@ class ChatItemArchiveExporter( } else -> { - if (record.body.isNullOrEmpty() && !extraData.attachmentsById.containsKey(record.id)) { - Log.w(TAG, ExportSkips.emptyChatItem(record.dateSent)) - continue - } - val attachments = extraData.attachmentsById[record.id] if (attachments?.isNotEmpty() == true && attachments.all { it.contentType == MediaUtil.LONG_TEXT } && record.body.isNullOrEmpty()) { Log.w(TAG, ExportSkips.invalidLongTextChatItem(record.dateSent)) @@ -313,20 +308,28 @@ class ChatItemArchiveExporter( if (sticker?.stickerLocator != null) { builder.stickerMessage = sticker.toRemoteStickerMessage(mediaArchiveEnabled = mediaArchiveEnabled, reactions = extraData.reactionsById[id]) } else { - builder.standardMessage = record.toRemoteStandardMessage( + val standardMessage = record.toRemoteStandardMessage( db = db, mediaArchiveEnabled = mediaArchiveEnabled, reactionRecords = extraData.reactionsById[id], mentions = extraData.mentionsById[id], attachments = extraData.attachmentsById[record.id] ) + + if (standardMessage.text == null && standardMessage.attachments.isEmpty()) { + Log.w(TAG, ExportSkips.emptyStandardMessage(record.dateSent)) + continue + } + + builder.standardMessage = standardMessage } } } if (record.latestRevisionId == null) { builder.revisions = revisionMap.remove(record.id)?.repairRevisions(builder) ?: emptyList() - buffer += builder.build() + val chatItem = builder.build().validateChatItem() ?: continue + buffer += chatItem } else { var previousEdits = revisionMap[record.latestRevisionId] if (previousEdits == null) { @@ -1324,6 +1327,23 @@ private fun ExecutorService.submitTyped(callable: Callable): Future { return this.submit(callable) } +fun ChatItem.validateChatItem(): ChatItem? { + if (this.standardMessage == null && + this.contactMessage == null && + this.stickerMessage == null && + this.remoteDeletedMessage == null && + this.updateMessage == null && + this.paymentNotification == null && + this.giftBadge == null && + this.viewOnceMessage == null && + this.directStoryReplyMessage == null + ) { + Log.w(TAG, ExportSkips.emptyChatItem(this.dateSent)) + return null + } + return this +} + fun List.repairRevisions(current: ChatItem.Builder): List { return if (current.standardMessage != null) { val filtered = this.filter { it.standardMessage != null }