diff --git a/core-util-jvm/src/main/java/org/signal/core/util/E164Util.kt b/core-util-jvm/src/main/java/org/signal/core/util/E164Util.kt index 502d14f959..79b0c1e16b 100644 --- a/core-util-jvm/src/main/java/org/signal/core/util/E164Util.kt +++ b/core-util-jvm/src/main/java/org/signal/core/util/E164Util.kt @@ -152,15 +152,20 @@ object E164Util { */ private fun formatAsE164WithRegionCode(localNumber: PhoneNumber?, localAreaCode: String?, regionCode: String, input: String): String? { try { - val withAreaCodeRules: String = applyAreaCodeRules(localNumber, localAreaCode, input.e164CharsOnly()) + val correctedInput = input.e164CharsOnly().stripLeadingZerosFromInput() + if (correctedInput.trimStart('0').length < 3) { + return null + } + + val withAreaCodeRules: String = applyAreaCodeRules(localNumber, localAreaCode, correctedInput) val parsedNumber: PhoneNumber = PhoneNumberUtil.getInstance().parse(withAreaCodeRules, regionCode) val isShortCode = ShortNumberInfo.getInstance().isValidShortNumberForRegion(parsedNumber, regionCode) || withAreaCodeRules.length <= 5 if (isShortCode) { - return input.numbersOnly() + return correctedInput.numbersOnly().stripLeadingZerosFromE164() } - return PhoneNumberUtil.getInstance().format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.E164) + return PhoneNumberUtil.getInstance().format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.E164).stripLeadingZerosFromE164() } catch (e: NumberParseException) { return null } @@ -208,6 +213,30 @@ object E164Util { return this.filter { it.isDigit() || it == '+' } } + /** + * Strips out bad leading zeros from input strings that can confuse libphonenumber. + */ + private fun String.stripLeadingZerosFromInput(): String { + return if (this.startsWith("+0")) { + "+" + this.substring(1).trimStart('0') + } else { + this + } + } + + /** + * Strips out leading zeros from a string after it's been e164-formatted by libphonenumber. + */ + private fun String.stripLeadingZerosFromE164(): String { + return if (this.startsWith("0")) { + this.trimStart('0') + } else if (this.startsWith("+0")) { + "+" + this.substring(1).trimStart('0') + } else { + this + } + } + class Formatter( val localNumber: PhoneNumber?, val localAreaCode: String?, diff --git a/core-util-jvm/src/test/java/org/signal/core/util/E164UtilTest.kt b/core-util-jvm/src/test/java/org/signal/core/util/E164UtilTest.kt index 9413e0b1e3..7b5c9124d7 100644 --- a/core-util-jvm/src/test/java/org/signal/core/util/E164UtilTest.kt +++ b/core-util-jvm/src/test/java/org/signal/core/util/E164UtilTest.kt @@ -52,6 +52,17 @@ class E164UtilTest { Assert.assertEquals("+442079460018", formatter.formatAsE164("(020) 7946 0018")) } + @Test + fun `formatAsE164 - strip leading zeros`() { + val formatter: E164Util.Formatter = E164Util.createFormatterForE164("+14152222222") + Assert.assertEquals("+15551234567", formatter.formatAsE164("+015551234567")) + Assert.assertEquals("+15551234567", formatter.formatAsE164("+0015551234567")) + Assert.assertEquals("+15551234567", formatter.formatAsE164("01115551234567")) + Assert.assertEquals("1234", formatter.formatAsE164("01234")) + Assert.assertEquals(null, formatter.formatAsE164("0")) + Assert.assertEquals(null, formatter.formatAsE164("0000000")) + } + @Test fun `formatAsE164 - US mix`() { val formatter: E164Util.Formatter = E164Util.createFormatterForE164("+16105880522") @@ -116,6 +127,10 @@ class E164UtilTest { Assert.assertEquals(null, formatter.formatAsE164("bonbon")) Assert.assertEquals(null, formatter.formatAsE164("44444444441234512312312312312312312312")) Assert.assertEquals(null, formatter.formatAsE164("144444444441234512312312312312312312312")) + Assert.assertEquals(null, formatter.formatAsE164("1")) + Assert.assertEquals(null, formatter.formatAsE164("55")) + Assert.assertEquals(null, formatter.formatAsE164("0")) + Assert.assertEquals(null, formatter.formatAsE164("000")) } @Test