Validate E164's in ContactRecords.

main
Greyson Parrelli 2023-02-23 17:45:20 -05:00 zatwierdzone przez Nicholas Tinsley
rodzic 33828439fb
commit 8334db5273
2 zmienionych plików z 112 dodań i 0 usunięć

Wyświetl plik

@ -28,11 +28,14 @@ import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
public class ContactRecordProcessor extends DefaultStorageRecordProcessor<SignalContactRecord> {
private static final String TAG = Log.tag(ContactRecordProcessor.class);
private static final Pattern E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{0,18}$");
private final RecipientTable recipientTable;
private final ACI selfAci;
@ -141,6 +144,9 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
} else if (!FeatureFlags.phoneNumberPrivacy() && remote.getServiceId().equals(remote.getPni().orElse(null))) {
Log.w(TAG, "Found a PNI-only ContactRecord when PNP is disabled -- marking as invalid.");
return true;
} else if (remote.getNumber().isPresent() && !isValidE164(remote.getNumber().get())) {
Log.w(TAG, "Found a record with an invalid E164. Marking as invalid.");
return true;
} else {
return false;
}
@ -321,6 +327,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
}
}
private static boolean isValidE164(String value) {
return E164_PATTERN.matcher(value).matches();
}
private static boolean doParamsMatch(@NonNull SignalContactRecord contact,
@Nullable byte[] unknownFields,
@NonNull ServiceId serviceId,

Wyświetl plik

@ -188,6 +188,108 @@ class ContactRecordProcessorTest {
assertFalse(result)
}
@Test
fun `isInvalid, valid E164, true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164(E164_B)
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertFalse(result)
}
@Test
fun `isInvalid, invalid E164 (missing +), true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164("15551234567")
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertTrue(result)
}
@Test
fun `isInvalid, invalid E164 (contains letters), true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164("+1555ABC4567")
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertTrue(result)
}
@Test
fun `isInvalid, invalid E164 (no numbers), true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164("+")
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertTrue(result)
}
@Test
fun `isInvalid, invalid E164 (too many numbers), true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164("+12345678901234567890")
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertTrue(result)
}
@Test
fun `isInvalid, invalid E164 (starts with zero), true`() {
// GIVEN
val subject = ContactRecordProcessor(ACI_A, PNI_A, E164_A, recipientTable)
val record = buildRecord {
setServiceId(ACI_B.toString())
setServiceE164("+05551234567")
}
// WHEN
val result = subject.isInvalid(record)
// THEN
assertTrue(result)
}
@Test
fun `merge, e164MatchesButPnisDont pnpEnabled, keepLocal`() {
// GIVEN