mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-25 22:38:49 +00:00
Fix backup/import issue with expiring messages.
There was an issue where we were backing up group receipts and attachments that were for expiring messages (which are already excluded from the backup). This commit excludes these items from the backup, and for backups made before this change, this commit also deletes these invalid entries at the end of the restore process. We also do a little database migration to cleanup any bad state that may have been imported in the past.
This commit is contained in:
@@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase;
|
||||
@@ -75,8 +76,10 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
for (String table : tables) {
|
||||
if (table.equals(SmsDatabase.TABLE_NAME) || table.equals(MmsDatabase.TABLE_NAME)) {
|
||||
count = exportTable(table, input, outputStream, cursor -> cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.EXPIRES_IN)) <= 0, null, count);
|
||||
} else if (table.equals(GroupReceiptDatabase.TABLE_NAME)) {
|
||||
count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(GroupReceiptDatabase.MMS_ID))), null, count);
|
||||
} else if (table.equals(AttachmentDatabase.TABLE_NAME)) {
|
||||
count = exportTable(table, input, outputStream, null, cursor -> exportAttachment(attachmentSecret, cursor, outputStream), count);
|
||||
count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.MMS_ID))), cursor -> exportAttachment(attachmentSecret, cursor, outputStream), count);
|
||||
} else if (!table.equals(SignedPreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(OneTimePreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(SessionDatabase.TABLE_NAME) &&
|
||||
@@ -229,6 +232,21 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isForNonExpiringMessage(@NonNull SQLiteDatabase db, long mmsId) {
|
||||
String[] columns = new String[] { MmsDatabase.EXPIRES_IN };
|
||||
String where = MmsDatabase.ID + " = ?";
|
||||
String[] args = new String[] { String.valueOf(mmsId) };
|
||||
|
||||
try (Cursor mmsCursor = db.query(MmsDatabase.TABLE_NAME, columns, where, args, null, null, null)) {
|
||||
if (mmsCursor != null && mmsCursor.moveToFirst()) {
|
||||
return mmsCursor.getLong(0) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static class BackupFrameOutputStream extends BackupStream {
|
||||
|
||||
private final OutputStream outputStream;
|
||||
@@ -358,9 +376,9 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.util.Pair;
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId;
|
||||
import org.thoughtcrime.securesms.backup.BackupProtos.Attachment;
|
||||
import org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame;
|
||||
import org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion;
|
||||
@@ -22,7 +23,12 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret;
|
||||
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.SearchDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -80,6 +86,8 @@ public class FullBackupImporter extends FullBackupBase {
|
||||
else if (frame.hasAvatar()) processAvatar(context, frame.getAvatar(), inputStream);
|
||||
}
|
||||
|
||||
trimEntriesForExpiredMessages(context, db);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
@@ -158,6 +166,27 @@ public class FullBackupImporter extends FullBackupBase {
|
||||
}
|
||||
}
|
||||
|
||||
private static void trimEntriesForExpiredMessages(@NonNull Context context, @NonNull SQLiteDatabase db) {
|
||||
String trimmedCondition = " NOT IN (SELECT " + MmsDatabase.ID + " FROM " + MmsDatabase.TABLE_NAME + ")";
|
||||
|
||||
db.delete(GroupReceiptDatabase.TABLE_NAME, GroupReceiptDatabase.MMS_ID + trimmedCondition, null);
|
||||
|
||||
String[] columns = new String[] { AttachmentDatabase.ROW_ID, AttachmentDatabase.UNIQUE_ID };
|
||||
String where = AttachmentDatabase.MMS_ID + trimmedCondition;
|
||||
|
||||
try (Cursor cursor = db.query(AttachmentDatabase.TABLE_NAME, columns, where, null, null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(new AttachmentId(cursor.getLong(0), cursor.getLong(1)));
|
||||
}
|
||||
}
|
||||
|
||||
try (Cursor cursor = db.query(ThreadDatabase.TABLE_NAME, new String[] { ThreadDatabase.ID }, ThreadDatabase.EXPIRES_IN + " > 0", null, null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
DatabaseFactory.getThreadDatabase(context).update(cursor.getLong(0), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BackupRecordInputStream extends BackupStream {
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
Reference in New Issue
Block a user