From 10e8c6d795de4eef5f76e2f8610e3da0d88e80dc Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Tue, 28 Feb 2023 10:58:23 -0500 Subject: [PATCH] Skip attachments with unrecoverable errors during sms export. --- .../crypto/ModernDecryptingPartInputStream.java | 4 +++- .../securesms/exporter/SignalSmsExportService.kt | 12 +++++++++++- .../java/org/signal/smsexporter/SmsExportService.kt | 11 +++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/ModernDecryptingPartInputStream.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/ModernDecryptingPartInputStream.java index 268d7a5f0..8e5bbee35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/ModernDecryptingPartInputStream.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/ModernDecryptingPartInputStream.java @@ -22,6 +22,8 @@ import javax.crypto.spec.SecretKeySpec; public class ModernDecryptingPartInputStream { + public static final String PREMATURE_END_ERROR_MESSAGE = "Prematurely reached end of stream!"; + public static InputStream createFor(@NonNull AttachmentSecret attachmentSecret, @NonNull byte[] random, @NonNull File file, long offset) throws IOException { @@ -75,7 +77,7 @@ public class ModernDecryptingPartInputStream { for (;;) { int read = in.read(buffer, offset, buffer.length-offset); - if (read == -1) throw new IOException("Prematurely reached end of stream!"); + if (read == -1) throw new IOException(PREMATURE_END_ERROR_MESSAGE); else if (read + offset < buffer.length) offset += read; else return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/exporter/SignalSmsExportService.kt b/app/src/main/java/org/thoughtcrime/securesms/exporter/SignalSmsExportService.kt index 9758b8c16..052b841c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/exporter/SignalSmsExportService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/exporter/SignalSmsExportService.kt @@ -9,6 +9,7 @@ import org.signal.smsexporter.ExportableMessage import org.signal.smsexporter.SmsExportService import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.attachments.AttachmentId +import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState @@ -19,6 +20,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels import org.thoughtcrime.securesms.notifications.NotificationIds import org.thoughtcrime.securesms.notifications.v2.NotificationPendingIntentHelper import org.thoughtcrime.securesms.util.JsonUtils +import java.io.EOFException import java.io.IOException import java.io.InputStream @@ -168,7 +170,15 @@ class SignalSmsExportService : SmsExportService() { @Throws(IOException::class) override fun getInputStream(part: ExportableMessage.Mms.Part): InputStream { - return SignalDatabase.attachments.getAttachmentStream(JsonUtils.fromJson(part.contentId, AttachmentId::class.java), 0) + try { + return SignalDatabase.attachments.getAttachmentStream(JsonUtils.fromJson(part.contentId, AttachmentId::class.java), 0) + } catch (e: IOException) { + if (e.message == ModernDecryptingPartInputStream.PREMATURE_END_ERROR_MESSAGE) { + throw EOFException(e.message) + } else { + throw e + } + } } override fun onExportPassCompleted() { diff --git a/sms-exporter/lib/src/main/java/org/signal/smsexporter/SmsExportService.kt b/sms-exporter/lib/src/main/java/org/signal/smsexporter/SmsExportService.kt index 11666dda0..cc5b7b87b 100644 --- a/sms-exporter/lib/src/main/java/org/signal/smsexporter/SmsExportService.kt +++ b/sms-exporter/lib/src/main/java/org/signal/smsexporter/SmsExportService.kt @@ -14,6 +14,7 @@ import org.signal.smsexporter.internal.mms.ExportMmsPartsUseCase import org.signal.smsexporter.internal.mms.ExportMmsRecipientsUseCase import org.signal.smsexporter.internal.mms.GetOrCreateMmsThreadIdsUseCase import org.signal.smsexporter.internal.sms.ExportSmsMessagesUseCase +import java.io.EOFException import java.io.FileNotFoundException import java.io.InputStream import java.util.concurrent.Executor @@ -346,8 +347,14 @@ abstract class SmsExportService : Service() { onAttachmentPartExportSucceeded(output.message, output.part) Try.success(Unit) } catch (e: Exception) { - Log.d(TAG, "Failed to write attachment to disk.", e) - Try.failure(e) + if (e is EOFException) { + Log.d(TAG, "Unrecoverable failure to write attachment to disk, marking as successful and moving on", e) + onAttachmentPartExportSucceeded(output.message, output.part) + Try.success(Unit) + } else { + Log.d(TAG, "Failed to write attachment to disk.", e) + Try.failure(e) + } } }