diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index 82b00a16c3..09bea00ad8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -27,10 +27,10 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; -import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import java.io.Closeable; import java.security.SecureRandom; @@ -200,9 +200,9 @@ public final class GroupDatabase extends Database { try (Cursor cursor = database.query(table, null, query, args, null, null, orderBy)) { while (cursor != null && cursor.moveToNext()) { - List members = Util.split(cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)), ","); + String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)); - if (members.contains(recipientId.serialize())) { + if (RecipientId.serializedListContains(serializedMembers, recipientId)) { groups.add(new Reader(cursor).getCurrent()); } } @@ -452,6 +452,23 @@ public final class GroupDatabase extends Database { database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId.toString()}); } + @WorkerThread + public boolean isCurrentMember(@NonNull GroupId.Push groupId, @NonNull RecipientId recipientId) { + SQLiteDatabase database = databaseHelper.getReadableDatabase(); + + try (Cursor cursor = database.query(TABLE_NAME, new String[] {MEMBERS}, + GROUP_ID + " = ?", new String[] {groupId.toString()}, + null, null, null)) + { + if (cursor.moveToNext()) { + String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)); + return RecipientId.serializedListContains(serializedMembers, recipientId); + } else { + return false; + } + } + } + private static String serializeV2GroupMembers(@NonNull Context context, @NonNull DecryptedGroup decryptedGroup) { List groupMembers = new ArrayList<>(decryptedGroup.getMembersCount()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupId.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupId.java index 9048e65cf6..42cea40ea3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupId.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupId.java @@ -19,7 +19,6 @@ public abstract class GroupId { private static final int MMS_BYTE_LENGTH = 16; private static final int V1_MMS_BYTE_LENGTH = 16; private static final int V2_BYTE_LENGTH = GroupIdentifier.SIZE; - private static final int V2_ENCODED_LENGTH = ENCODED_SIGNAL_GROUP_PREFIX.length() + V2_BYTE_LENGTH * 2; private final String encodedId; @@ -63,6 +62,10 @@ public abstract class GroupId { .getGroupIdentifier()); } + public static GroupId.Push push(byte[] bytes) { + return bytes.length == V2_BYTE_LENGTH ? v2(bytes) : v1(bytes); + } + public static @NonNull GroupId parse(@NonNull String encodedGroupId) { try { if (!isEncodedGroup(encodedGroupId)) { @@ -71,10 +74,7 @@ public abstract class GroupId { byte[] bytes = extractDecodedId(encodedGroupId); - if (encodedGroupId.startsWith(ENCODED_MMS_GROUP_PREFIX)) return mms(bytes); - else if (encodedGroupId.length() == V2_ENCODED_LENGTH) return v2(bytes); - else return v1(bytes); - + return encodedGroupId.startsWith(ENCODED_MMS_GROUP_PREFIX) ? mms(bytes) : push(bytes); } catch (IOException e) { throw new AssertionError(e); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java index daf53f6c35..6bf6106b77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java @@ -1324,8 +1324,14 @@ public final class PushProcessMessageJob extends BaseJob { long threadId; if (typingMessage.getGroupId().isPresent()) { - RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupId.v1(typingMessage.getGroupId().get())); - Recipient groupRecipient = Recipient.resolved(recipientId); + GroupId.Push groupId = GroupId.push(typingMessage.getGroupId().get()); + + if (!DatabaseFactory.getGroupDatabase(context).isCurrentMember(groupId, author.getId())) { + Log.w(TAG, "Seen typing indicator for non-member"); + return; + } + + Recipient groupRecipient = Recipient.externalGroup(context, groupId); threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java index 092ee8f022..aa96ade38e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.util.Util; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; public class RecipientId implements Parcelable, Comparable { @@ -62,6 +63,12 @@ public class RecipientId implements Parcelable, Comparable { return out; } + public static boolean serializedListContains(@NonNull String serialized, @NonNull RecipientId recipientId) { + return Pattern.compile("\\b" + recipientId.serialize() + "\\b") + .matcher(serialized) + .find(); + } + public boolean isUnknown() { return id == UNKNOWN_ID; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/DelimiterUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/DelimiterUtil.java index a338cc9f79..bf27f659cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/DelimiterUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/DelimiterUtil.java @@ -1,8 +1,6 @@ package org.thoughtcrime.securesms.util; -import android.text.TextUtils; - import java.util.regex.Pattern; public class DelimiterUtil { @@ -16,7 +14,7 @@ public class DelimiterUtil { } public static String[] split(String value, char delimiter) { - if (TextUtils.isEmpty(value)) { + if (value == null || value.length() == 0) { return new String[0]; } else { String regex = "(?