Prevent reading UUIDs from external contacts.

master
Greyson Parrelli 2019-11-25 11:04:45 -05:00
parent 6d78e1760d
commit 6108a32631
2 changed files with 23 additions and 2 deletions

View File

@ -14,6 +14,7 @@ import android.provider.ContactsContract;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Collectors;
@ -42,6 +43,7 @@ import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.IOException;
import java.util.Calendar;
@ -140,8 +142,8 @@ class DirectoryHelperV1 {
while (cursor != null && cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (!TextUtils.isEmpty(number)) {
RecipientId recipientId = Recipient.external(context, number).getId();
if (isValidContactNumber(number)) {
RecipientId recipientId = Recipient.externalContact(context, number).getId();
String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String contactPhotoUri = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
String contactLabel = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LABEL));
@ -303,6 +305,9 @@ class DirectoryHelperV1 {
});
}
private static boolean isValidContactNumber(@Nullable String number) {
return !TextUtils.isEmpty(number) && !UuidUtil.isUuid(number);
}
private static class DirectoryResult {

View File

@ -186,6 +186,22 @@ public class Recipient {
}
}
/**
* A safety wrapper around {@link #external(Context, String)} for when you know you're using an
* identifier for a system contact, and therefore always want to prevent interpreting it as a
* UUID. This will crash if given a UUID.
*
* (This may seem strange, but apparently some devices are returning valid UUIDs for contacts)
*/
@WorkerThread
public static @NonNull Recipient externalContact(@NonNull Context context, @NonNull String identifier) {
if (UuidUtil.isUuid(identifier)) {
throw new UuidRecipientError();
} else {
return external(context, identifier);
}
}
/**
* Returns a fully-populated {@link Recipient} based off of a string identifier, creating one in
* the database if necessary. The identifier may be a uuid, phone number, email,