diff --git a/cpp/src/phonenumbers/shortnumberinfo.cc b/cpp/src/phonenumbers/shortnumberinfo.cc index cc6876e9e..057720e08 100644 --- a/cpp/src/phonenumbers/shortnumberinfo.cc +++ b/cpp/src/phonenumbers/shortnumberinfo.cc @@ -16,6 +16,7 @@ #include "phonenumbers/shortnumberinfo.h" +#include #include #include #include @@ -93,6 +94,18 @@ bool MatchesPossibleNumberAndNationalNumber( } } // namespace +// Helper method to check that the country calling code of the number matches +// the region it's being dialed from. +bool ShortNumberInfo::RegionDialingFromMatchesNumber(const PhoneNumber& number, + const string& region_dialing_from) const { + list region_codes; + phone_util_.GetRegionCodesForCountryCallingCode(number.country_code(), + ®ion_codes); + return std::find(region_codes.begin(), + region_codes.end(), + region_dialing_from) != region_codes.end(); +} + bool ShortNumberInfo::IsPossibleShortNumberForRegion( const string& short_number, const string& region_dialing_from) const { const PhoneMetadata* phone_metadata = @@ -106,6 +119,9 @@ bool ShortNumberInfo::IsPossibleShortNumberForRegion( bool ShortNumberInfo::IsPossibleShortNumberForRegion(const PhoneNumber& number, const string& region_dialing_from) const { + if (!RegionDialingFromMatchesNumber(number, region_dialing_from)) { + return false; + } const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { @@ -156,6 +172,9 @@ bool ShortNumberInfo::IsValidShortNumberForRegion( bool ShortNumberInfo::IsValidShortNumberForRegion( const PhoneNumber& number, const string& region_dialing_from) const { + if (!RegionDialingFromMatchesNumber(number, region_dialing_from)) { + return false; + } const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { @@ -217,6 +236,9 @@ ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCostForRegion( ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCostForRegion( const PhoneNumber& number, const string& region_dialing_from) const { + if (!RegionDialingFromMatchesNumber(number, region_dialing_from)) { + return ShortNumberInfo::UNKNOWN_COST; + } const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { diff --git a/cpp/src/phonenumbers/shortnumberinfo.h b/cpp/src/phonenumbers/shortnumberinfo.h index 4a405f59a..5cb80761e 100644 --- a/cpp/src/phonenumbers/shortnumberinfo.h +++ b/cpp/src/phonenumbers/shortnumberinfo.h @@ -216,6 +216,9 @@ class ShortNumberInfo { const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegion( const string& region_code) const; + bool RegionDialingFromMatchesNumber(const PhoneNumber& number, + const string& region_dialing_from) const; + // Helper method to get the region code for a given phone number, from a list // of possible region codes. If the list contains more than one region, the // first region for which the number is valid is returned. diff --git a/cpp/test/phonenumbers/shortnumberinfo_test.cc b/cpp/test/phonenumbers/shortnumberinfo_test.cc index 690fea085..fd42779d2 100644 --- a/cpp/test/phonenumbers/shortnumberinfo_test.cc +++ b/cpp/test/phonenumbers/shortnumberinfo_test.cc @@ -466,5 +466,18 @@ TEST_F(ShortNumberInfoTest, OverlappingNANPANumber) { ParseNumberForTesting("211", RegionCode::CA()), RegionCode::CA())); } +TEST_F(ShortNumberInfoTest, CountryCallingCodeIsNotIgnored) { + // +46 is the country calling code for Sweden (SE), and 40404 is a valid short + // number in the US. + EXPECT_FALSE(short_info_.IsPossibleShortNumberForRegion( + ParseNumberForTesting("+4640404", RegionCode::SE()), RegionCode::US())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("+4640404", RegionCode::SE()), RegionCode::US())); + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("+4640404", RegionCode::SE()), + RegionCode::US())); +} + } // namespace phonenumbers } // namespace i18n diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java index 0e1056c78..c0d01b4e1 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java @@ -100,6 +100,16 @@ public class ShortNumberInfo { : regionCodes); } + /** + * Helper method to check that the country calling code of the number matches the region it's + * being dialed from. + */ + private boolean regionDialingFromMatchesNumber(PhoneNumber number, + String regionDialingFrom) { + List regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + return regionCodes.contains(regionDialingFrom); + } + /** * Check whether a short number is a possible number when dialled from a region, given the number * in the form of a string, and the region where the number is dialed from. This provides a more @@ -133,6 +143,9 @@ public class ShortNumberInfo { * @return whether the number is a possible short number */ public boolean isPossibleShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + if (!regionDialingFromMatchesNumber(number, regionDialingFrom)) { + return false; + } PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); if (phoneMetadata == null) { @@ -205,6 +218,9 @@ public class ShortNumberInfo { * @return whether the short number matches a valid pattern */ public boolean isValidShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + if (!regionDialingFromMatchesNumber(number, regionDialingFrom)) { + return false; + } PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); if (phoneMetadata == null) { @@ -317,6 +333,9 @@ public class ShortNumberInfo { * category. */ public ShortNumberCost getExpectedCostForRegion(PhoneNumber number, String regionDialingFrom) { + if (!regionDialingFromMatchesNumber(number, regionDialingFrom)) { + return ShortNumberCost.UNKNOWN_COST; + } // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion( regionDialingFrom); diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java index 63661a903..edcb004c1 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java @@ -333,6 +333,17 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { shortInfo.getExpectedCostForRegion(parse("211", RegionCode.CA), RegionCode.CA)); } + public void testCountryCallingCodeIsNotIgnored() { + // +46 is the country calling code for Sweden (SE), and 40404 is a valid short number in the US. + assertFalse(shortInfo.isPossibleShortNumberForRegion( + parse("+4640404", RegionCode.SE), RegionCode.US)); + assertFalse(shortInfo.isValidShortNumberForRegion( + parse("+4640404", RegionCode.SE), RegionCode.US)); + assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, + shortInfo.getExpectedCostForRegion( + parse("+4640404", RegionCode.SE), RegionCode.US)); + } + private PhoneNumber parse(String number, String regionCode) { try { return phoneUtil.parse(number, regionCode); diff --git a/resources/PhoneNumberMetadataForTesting.xml b/resources/PhoneNumberMetadataForTesting.xml index 7b650b26e..085e00a95 100644 --- a/resources/PhoneNumberMetadataForTesting.xml +++ b/resources/PhoneNumberMetadataForTesting.xml @@ -780,6 +780,10 @@ + + + +