From fa425567bfb95b45c4899ab75b1a6da0130e4503 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 4 Oct 2024 16:58:49 -0400 Subject: [PATCH] Be more lenient when backing up possibly-invalid recipients. --- .../backup/v2/exporters/ContactArchiveExporter.kt | 13 ++++++++++--- .../v2/processor/RecipientArchiveProcessor.kt | 6 ++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ContactArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ContactArchiveExporter.kt index bec86d97e0..e7bd9b53fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ContactArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ContactArchiveExporter.kt @@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.backup.v2.exporters import android.database.Cursor import okio.ByteString.Companion.toByteString import org.signal.core.util.Base64 +import org.signal.core.util.logging.Log import org.signal.core.util.requireBoolean import org.signal.core.util.requireInt import org.signal.core.util.requireLong @@ -26,12 +27,17 @@ import java.io.Closeable * Provides a nice iterable interface over a [RecipientTable] cursor, converting rows to [ArchiveRecipient]s. * Important: Because this is backed by a cursor, you must close it. It's recommended to use `.use()` or try-with-resources. */ -class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Long) : Iterator, Closeable { +class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Long) : Iterator, Closeable { + + companion object { + private val TAG = Log.tag(ContactArchiveExporter::class) + } + override fun hasNext(): Boolean { return cursor.count > 0 && !cursor.isLast } - override fun next(): ArchiveRecipient { + override fun next(): ArchiveRecipient? { if (!cursor.moveToNext()) { throw NoSuchElementException() } @@ -49,7 +55,8 @@ class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Lon val e164 = cursor.requireString(RecipientTable.E164)?.e164ToLong() if (aci == null && pni == null && e164 == null) { - throw IllegalStateException("Should not happen! Query guards against this.") + Log.w(TAG, "All identifiers are null! Before parsing, ACI: ${cursor.requireString(RecipientTable.ACI_COLUMN) != null}, PNI: ${cursor.requireString(RecipientTable.PNI_COLUMN) != null}, E164: ${cursor.requireString(RecipientTable.E164) != null}") + return null } val contactBuilder = Contact.Builder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientArchiveProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientArchiveProcessor.kt index 40ef804b6d..ef8104cf91 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientArchiveProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientArchiveProcessor.kt @@ -51,8 +51,10 @@ object RecipientArchiveProcessor { db.recipientTable.getContactsForBackup(selfId).use { reader -> for (recipient in reader) { - exportState.recipientIds.add(recipient.id) - emitter.emit(Frame(recipient = recipient)) + if (recipient != null) { + exportState.recipientIds.add(recipient.id) + emitter.emit(Frame(recipient = recipient)) + } } }