Improve e164 normalization check by re-parsing without country code

This commit is contained in:
Chris Eager 2022-08-10 12:24:01 -05:00 committed by Chris Eager
parent 6d0345d327
commit 06eb890761
2 changed files with 28 additions and 5 deletions

View File

@ -42,11 +42,30 @@ public class Util {
}
try {
final PhoneNumber phoneNumber = PHONE_NUMBER_UTIL.parse(number, null);
final String normalizedNumber = PHONE_NUMBER_UTIL.format(phoneNumber, PhoneNumberFormat.E164);
final PhoneNumber inputNumber = PHONE_NUMBER_UTIL.parse(number, null);
if (!number.equals(normalizedNumber)) {
throw new NonNormalizedPhoneNumberException(number, normalizedNumber);
// For normalization, we want to format from a version parsed with the country code removed.
// This handles some cases of "possible", but non-normalized input numbers with a doubled country code, that is
// with the format "+{country code} {country code} {national number}"
final int countryCode = inputNumber.getCountryCode();
final String region = PHONE_NUMBER_UTIL.getRegionCodeForCountryCode(countryCode);
final PhoneNumber normalizedNumber = switch (region) {
// the country code has no associated region. Be lenient (and simple) and accept the input number
case "ZZ", "001" -> inputNumber;
default -> {
final String maybeLeadingZero =
inputNumber.hasItalianLeadingZero() && inputNumber.isItalianLeadingZero() ? "0" : "";
yield PHONE_NUMBER_UTIL.parse(
maybeLeadingZero + inputNumber.getNationalNumber(), region);
}
};
final String normalizedE164 = PHONE_NUMBER_UTIL.format(normalizedNumber,
PhoneNumberFormat.E164);
if (!number.equals(normalizedE164)) {
throw new NonNormalizedPhoneNumberException(number, normalizedE164);
}
} catch (final NumberParseException e) {
throw new ImpossiblePhoneNumberException(e);

View File

@ -24,11 +24,13 @@ class ValidNumberTest {
"+71234567890",
"+447535742222",
"+4915174108888",
"+2250707312345",
"+298123456",
"+299123456",
"+376123456",
"+68512345",
"+689123456"})
"+689123456",
"+80011111111"})
void requireNormalizedNumber(final String number) {
assertDoesNotThrow(() -> Util.requireNormalizedNumber(number));
}
@ -56,6 +58,8 @@ class ValidNumberTest {
@ParameterizedTest
@ValueSource(strings = {
"+4407700900111",
"+49493023125000", // double country code - this e164 is "possible"
"+494915110000000", // double country code - this e164 is "possible" and "valid"
"+1 415 123 1234",
"+1 (415) 123-1234",
"+1 415)123-1234",