diff --git a/cpp/src/phonenumbers/phonenumbermatcher.cc b/cpp/src/phonenumbers/phonenumbermatcher.cc index 794c3c682e..87e99004cb 100644 --- a/cpp/src/phonenumbers/phonenumbermatcher.cc +++ b/cpp/src/phonenumbers/phonenumbermatcher.cc @@ -123,7 +123,10 @@ bool AllNumberGroupsRemainGrouped( if (number.country_code_source() != PhoneNumber::FROM_DEFAULT_COUNTRY) { // First skip the country code if the normalized candidate contained it. string country_code = SimpleItoa(number.country_code()); - from_index = normalized_candidate.find(country_code) + country_code.size(); + size_t country_code_index = normalized_candidate.find(country_code); + if (country_code_index != string::npos) { + from_index = country_code_index + country_code.size(); + } } // Check each group of consecutive digits are not broken into separate // groupings in the normalized_candidate string. diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java index b812551db0..0d130edf01 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberMatcher.java @@ -463,7 +463,10 @@ static boolean allNumberGroupsRemainGrouped(PhoneNumberUtil util, if (number.getCountryCodeSource() != CountryCodeSource.FROM_DEFAULT_COUNTRY) { // First skip the country code if the normalized candidate contained it. String countryCode = Integer.toString(number.getCountryCode()); - fromIndex = normalizedCandidate.indexOf(countryCode) + countryCode.length(); + int countryCodeIndex = normalizedCandidate.indexOf(countryCode); + if (countryCodeIndex >= 0) { + fromIndex = countryCodeIndex + countryCode.length(); + } } // Check each group of consecutive digits are not broken into separate groupings in the // {@code normalizedCandidate} string. diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java index d31b33951b..a00255014d 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberMatcherTest.java @@ -77,6 +77,21 @@ public void testContainsMoreThanOneSlashInNationalNumber() throws Exception { assertTrue(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); } + public void testAllNumberGroupsRemainGroupedCountryCodeNotInCandidate() throws Exception { + // Constructed case: the country code source claims the candidate began with an explicit + // country calling code, but the literal digits of that code ("44") do not actually occur in + // the candidate text. Previously this desynced fromIndex (indexOf returns -1, and -1 plus the + // country code's length was used as a starting position instead of being treated as "not + // found"), which made a grouping match that should succeed incorrectly return false. + PhoneNumber number = new PhoneNumber(); + number.setCountryCode(44); + number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN); + StringBuilder candidate = new StringBuilder("020 7031 3000"); + String[] formattedNumberGroups = {"020", "7031", "3000"}; + assertTrue(PhoneNumberMatcher.allNumberGroupsRemainGrouped( + phoneUtil, number, candidate, formattedNumberGroups)); + } + /** See {@link PhoneNumberUtilTest#testParseNationalNumber()}. */ public void testFindNationalNumber() throws Exception { // same cases as in testParseNationalNumber