diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SignalE164Util.kt b/app/src/main/java/org/thoughtcrime/securesms/util/SignalE164Util.kt index 2c584ef305..da0a3901fb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SignalE164Util.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SignalE164Util.kt @@ -60,14 +60,14 @@ object SignalE164Util { * This does not check if the number is *valid* for a given region. Instead, it's very lenient and just * does it's best to interpret the input string as a number that could be put into the E164 format. * - * Note that shortcodes will not have leading '+' signs. + * Note that shortcodes will return null. * * In other words, if this method returns null, you likely do not have anything that could be considered * a phone number. */ @JvmStatic fun formatNonShortCodeAsE164(input: String): String? { - return getFormatter().formatAsE164(input)?.takeIf { input.trimStart('+', '0').length > 6 } + return getFormatter().formatAsE164(input)?.takeIf { !getFormatter().isValidShortNumber(input) } } /** 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 61834a20a6..f7dcc6362f 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 @@ -173,6 +173,37 @@ object E164Util { } } + /** + * Strictly checks if a given number is a valid short code for a given region. Short code length varies by region and some + * require specific prefixes. + * + * This will check the input with and without a leading '+' sign. + * + * If the number cannot be parsed or is otherwise invalid, false is returned. + */ + private fun isValidShortNumber(regionCode: String, input: String): Boolean { + try { + val correctedInput = input.e164CharsOnly().stripLeadingZerosFromInput() + val correctedWithoutLeading = correctedInput.trimStart('+', '0') + + var parsedNumber: PhoneNumber = PhoneNumberUtil.getInstance().parse(correctedInput, regionCode) + + val isShortCode = ShortNumberInfo.getInstance().isValidShortNumberForRegion(parsedNumber, regionCode) || correctedWithoutLeading.length <= 6 + if (isShortCode) { + return true + } + + if (correctedInput != correctedWithoutLeading) { + parsedNumber = PhoneNumberUtil.getInstance().parse(correctedInput.trimStart('+', '0'), regionCode) + return ShortNumberInfo.getInstance().isValidShortNumberForRegion(parsedNumber, regionCode) || correctedInput.length <= 6 + } + + return false + } catch (_: NumberParseException) { + return false + } + } + /** * Attempts to parse the area code out of an e164-formatted number provided that it's in one of the supported countries. */ @@ -273,6 +304,10 @@ object E164Util { } } + fun isValidShortNumber(input: String): Boolean { + return isValidShortNumber(localRegionCode, input) + } + /** * Formats the number for human-readable display. e.g. "(555) 555-5555" */ 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 9d6a356a55..8eb7b3e72b 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 @@ -155,4 +155,25 @@ class E164UtilTest { val formatter: E164Util.Formatter = E164Util.createFormatterForRegionCode("US") Assert.assertEquals("+14151111122", formatter.formatAsE164("(415) 111-1122")) } + + @Test + fun `isValidShortNumber - multiple regions`() { + // India + var formatter: E164Util.Formatter = E164Util.createFormatterForE164("+911234567890") + Assert.assertTrue(formatter.isValidShortNumber("543212601")) + Assert.assertTrue(formatter.isValidShortNumber("+543212601")) + Assert.assertFalse(formatter.isValidShortNumber("1234567890")) + + // Australia + formatter = E164Util.createFormatterForE164("+61111111111") + Assert.assertTrue(formatter.isValidShortNumber("1258881")) + Assert.assertTrue(formatter.isValidShortNumber("+1258881")) + Assert.assertFalse(formatter.isValidShortNumber("+111111111")) + + // US + formatter = E164Util.createFormatterForE164("+15555555555") + Assert.assertTrue(formatter.isValidShortNumber("125811")) + Assert.assertTrue(formatter.isValidShortNumber("+121581")) + Assert.assertFalse(formatter.isValidShortNumber("+15555555555")) + } }