Cleanup mentions with bad thread ids or ranges, or duplicates.

master
Cody Henthorne 2020-10-02 11:24:59 -04:00 committed by Alan Evans
parent fde9f05bd0
commit 3179808f17
2 changed files with 42 additions and 5 deletions

View File

@ -16,7 +16,6 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.MentionSetting;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.signalservice.api.util.UuidUtil;
@ -24,6 +23,8 @@ import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
public final class MentionUtil {
@ -68,14 +69,13 @@ public final class MentionUtil {
return new UpdatedBodyAndMentions(body, mentions);
}
SortedSet<Mention> sortedMentions = new TreeSet<>(mentions);
SpannableStringBuilder updatedBody = new SpannableStringBuilder();
List<Mention> updatedMentions = new ArrayList<>();
Collections.sort(mentions);
int bodyIndex = 0;
for (Mention mention : mentions) {
for (Mention mention : sortedMentions) {
updatedBody.append(body.subSequence(bodyIndex, mention.getStart()));
CharSequence replaceWith = replacementTextGenerator.apply(mention);
Mention updatedMention = new Mention(mention.getRecipientId(), updatedBody.length(), replaceWith.length());

View File

@ -62,14 +62,17 @@ import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.SqlUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Triple;
import org.thoughtcrime.securesms.util.Util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@ -151,8 +154,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int THUMBNAIL_CLEANUP = 74;
private static final int STICKER_CONTENT_TYPE_CLEANUP = 75;
private static final int MENTION_CLEANUP = 76;
private static final int MENTION_CLEANUP_V2 = 77;
private static final int DATABASE_VERSION = 76;
private static final int DATABASE_VERSION = 77;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@ -1086,6 +1090,39 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
}
}
if (oldVersion < MENTION_CLEANUP_V2) {
String selectMentionIdsWithMismatchingThreadIds = "select mention._id from mention left join mms on mention.message_id = mms._id where mention.thread_id != mms.thread_id";
db.delete("mention", "_id in (" + selectMentionIdsWithMismatchingThreadIds + ")", null);
List<Long> idsToDelete = new LinkedList<>();
Set<Triple<Long, Integer, Integer>> mentionTuples = new HashSet<>();
try (Cursor cursor = db.rawQuery("select mention.*, mms.body from mention inner join mms on mention.message_id = mms._id order by mention._id desc", null)) {
while (cursor != null && cursor.moveToNext()) {
long mentionId = CursorUtil.requireLong(cursor, "_id");
long messageId = CursorUtil.requireLong(cursor, "message_id");
int rangeStart = CursorUtil.requireInt(cursor, "range_start");
int rangeLength = CursorUtil.requireInt(cursor, "range_length");
String body = CursorUtil.requireString(cursor, "body");
if (body != null && rangeStart < body.length() && body.charAt(rangeStart) != '\uFFFC') {
idsToDelete.add(mentionId);
} else {
Triple<Long, Integer, Integer> tuple = new Triple<>(messageId, rangeStart, rangeLength);
if (mentionTuples.contains(tuple)) {
idsToDelete.add(mentionId);
} else {
mentionTuples.add(tuple);
}
}
}
if (Util.hasItems(idsToDelete)) {
String ids = TextUtils.join(",", idsToDelete);
db.delete("mention", "_id in (" + ids + ")", null);
}
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();