mobi / telephone_number

Phone number validation for Ruby
MIT License
385 stars 32 forks source link

e164 formatted number contains duplicate country code #99

Closed asms closed 1 year ago

asms commented 3 years ago

Gem Version: 1.4.9 and 1.4.11 Ruby Version: 2.6.6

Example (last 4 digits anonymized):

irb(main):006:0> TelephoneNumber.parse('+4917880xxxx').e164_number
=> "+494917880"

You can see that the input number starts with 49, but the e164 number starts with 4949.

asms commented 3 years ago

I think there are two parts to this bug: 1) the number is deemed invalid despite being a valid o2/telefonica number this should be filed with libphonenumber 2) the telephone_number is still adding a duplicate 49 to the number. Even if it doesn't think that it's valid, since it starts with +, it should probably return a best guess which would be the original number. Alternatively, it should return nil or raise an error.

tvandergeer commented 3 years ago

We're running into a similar issue. In our case we're doing the following:

TelephoneNumber.parse("+96279nnnnnnn","DE").international_number
"+49 9627 9nnnnnnn"

(obfuscated last 7 digits for privacy)

In this case it's a Jordan (JO) number, but it's formatted with the German (DE) prefix. This doesn't happen for other country codes, e.g.

TelephoneNumber.parse("+96279nnnnnnn","NL").international_number
=> "96279nnnnnnn"

And the appspot demo for libphonenumber also returns the correct result: https://libphonenumber.appspot.com/phonenumberparser?number=%2B96279nnnnnnn&country=DE (surprise: it kinda works with my obfuscated number)

tvandergeer commented 3 years ago

Investigating OP's scenario; it turns out that their problem is also related to German (DE/+49) phone numbers. Testing with Dutch (NL/+31) phonenumber show that those work correct.

irb(main):012:0> TelephoneNumber.parse('+4917880xxxx').e164_number
=> "+494917880"
irb(main):013:0> TelephoneNumber.parse('+3162700xxxx').e164_number
=> "3162700"

Seems that OP's problem and the issue I reported are in fact related and specific for German number formatting. Either being a German number or parsing according to a German number plan.

I've ruled out a problem with the Metadata, because other implementations (e.g. javascript) don't display this behavior.

tvandergeer commented 3 years ago

Turns out there are more problem with this gem. E.g. it does not seem to respect the "internationalPrefix" property in the Metadata. Hence the following number is invalid, while in fact it is perfectly fine:

TelephoneNumber.parse('01131887746420', 'US').valid?
=> false

This does work:

TelephoneNumber.parse('+31887746420', 'US').valid?
=> true

We're considering switching to https://github.com/daddyz/phonelib

pranavkedia commented 1 year ago

There are 2 things going on here. 491 is a valid area code inside Germany. Also 49 is country code for Germany. The gem gets confused when it is given an invalid number.

In the example above +4917880xxxx is not valid German number. It is not sufficiently long. Hence this gem tries to be smart and treats 491 as an area code inside Germany and adds 49 as the country code. This is one of the bugs, but there is a deeper bug that I describe a bit later. If we pass a valid telephone number, it behaves well.

irb(main):060:0> TelephoneNumber.parse('+49178801234').e164_number
=> "+4949178801234"
irb(main):061:0> TelephoneNumber.parse('+491788012345').e164_number
=> "+491788012345"
irb(main):062:0>

The real issue is that the first number is not a valid number, but this gem still says it is valid

irb(main):062:0> TelephoneNumber.parse('+49178801234').valid?
=> true
irb(main):063:0> TelephoneNumber.parse('+491788012345').valid?
=> true
irb(main):064:0>

The validation is broken. Here is another example

irb(main):070:0> TelephoneNumber.parse('+491788').valid?
=> true
irb(main):071:0> TelephoneNumber.parse('+491788').e164_number
=> "+49491788"
irb(main):072:0>

For the correct telephone number length in Germany, please see https://en.wikipedia.org/wiki/Telephone_numbers_in_Germany The following describes the 491 area code in Germany https://en.wikipedia.org/wiki/List_of_dialling_codes_in_Germany#0491_%E2%80%93_Leer_and_surroundings

I wonder if there is a knob by which we can ask it to do a correct length check?