Skip to content

Commit 2d3f07b

Browse files
authored
Merge pull request #564 from giggsey/upstream-8.13.8
Upstream changes for v8.13.8
2 parents 281b12d + 3329fcd commit 2d3f07b

23 files changed

+231
-65
lines changed

METADATA-VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# It can be a commit, branch or tag of the https://github.com/google/libphonenumber project
33
#
44
# For more information, look at the phing tasks in build.xml
5-
v8.13.7
5+
v8.13.8

src/AsYouTypeFormatter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ private function inputDigitWithOptionToRememberPosition($nextChar, $rememberPosi
476476
case 1:
477477
case 2:
478478
return $this->accruedInput;
479-
/** @noinspection PhpMissingBreakStatementInspection */
479+
/** @noinspection PhpMissingBreakStatementInspection */
480480
case 3:
481481
if ($this->attemptToExtractIdd()) {
482482
$this->isExpectingCountryCallingCode = true;
@@ -485,8 +485,8 @@ private function inputDigitWithOptionToRememberPosition($nextChar, $rememberPosi
485485
$this->extractedNationalPrefix = $this->removeNationalPrefixFromNationalNumber();
486486
return $this->attemptToChooseFormattingPattern();
487487
}
488-
// fall through
489-
// no break
488+
// fall through
489+
// no break
490490
default:
491491
if ($this->isExpectingCountryCallingCode) {
492492
if ($this->attemptToExtractCountryCallingCode()) {

src/NumberParseException.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,31 @@
88
*/
99
class NumberParseException extends \Exception
1010
{
11+
/**
12+
* The country code supplied did not belong to a supported country or non-geographical entity.
13+
*/
1114
const INVALID_COUNTRY_CODE = 0;
12-
// This generally indicates the string passed in had less than 3 digits in it. More
13-
// specifically, the number failed to match the regular expression VALID_PHONE_NUMBER in
14-
// PhoneNumberUtil.
15+
/**
16+
* This indicates the string passed is not a valid number. Either the string had less than 3
17+
* digits in it or had an invalid phone-context parameter. More specifically, the number failed
18+
* to match the regular expression VALID_PHONE_NUMBER, RFC3966_GLOBAL_NUMBER_DIGITS, or
19+
* RFC3966_DOMAINNAME in PhoneNumberUtil
20+
*/
1521
const NOT_A_NUMBER = 1;
16-
// This indicates the string started with an international dialing prefix, but after this was
17-
// stripped from the number, had less digits than any valid phone number (including country
18-
// code) could have.
22+
/**
23+
* This indicates the string started with an international dialing prefix, but after this was
24+
* stripped from the number, had less digits than any valid phone number (including country
25+
* code) could have.
26+
*/
1927
const TOO_SHORT_AFTER_IDD = 2;
20-
// This indicates the string, after any country code has been stripped, had less digits than any
21-
// valid phone number could have.
28+
/**
29+
* This indicates the string, after any country code has been stripped, had less digits than any
30+
* valid phone number could have.
31+
*/
2232
const TOO_SHORT_NSN = 3;
23-
// This indicates the string had more digits than any valid phone number could have.
33+
/**
34+
* This indicates the string had more digits than any valid phone number could have.
35+
*/
2436
const TOO_LONG = 4;
2537

2638
protected $errorType;

src/PhoneNumber.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ public function equals(PhoneNumber $other)
528528
(!$this->hasCountryCodeSource() || $this->getCountryCodeSource() == $other->getCountryCodeSource());
529529
$samePrefCar = $this->hasPreferredDomesticCarrierCode() == $other->hasPreferredDomesticCarrierCode() &&
530530
(!$this->hasPreferredDomesticCarrierCode() || $this->getPreferredDomesticCarrierCode(
531-
) == $other->getPreferredDomesticCarrierCode());
531+
) == $other->getPreferredDomesticCarrierCode());
532532
return $sameType && $sameCountry && $sameNational && $sameExt && $sameLead && $sameZeros && $sameRaw && $sameCountrySource && $samePrefCar;
533533
}
534534

@@ -601,7 +601,7 @@ public function __unserialize($data)
601601
$this->rawInput,
602602
$this->countryCodeSource,
603603
$this->preferredDomesticCarrierCode
604-
) = $data;
604+
) = $data;
605605

606606
if ($this->numberOfLeadingZeros > 1) {
607607
$this->hasNumberOfLeadingZeros = true;

src/PhoneNumberMatcher.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,8 @@ public static function allNumberGroupsAreExactlyPresent(
602602
// Starting from the end, go through in reverse, excluding the first group, and check the
603603
// candidate and number groups are the same.
604604
for ($formattedNumberGroupIndex = (\count($formattedNumberGroups) - 1);
605-
$formattedNumberGroupIndex > 0 && $candidateNumberGroupIndex >= 0;
606-
$formattedNumberGroupIndex--, $candidateNumberGroupIndex--) {
605+
$formattedNumberGroupIndex > 0 && $candidateNumberGroupIndex >= 0;
606+
$formattedNumberGroupIndex--, $candidateNumberGroupIndex--) {
607607
if ($candidateGroups[$candidateNumberGroupIndex] != $formattedNumberGroups[$formattedNumberGroupIndex]) {
608608
return false;
609609
}

src/PhoneNumberUtil.php

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,20 @@ class PhoneNumberUtil
224224
* @internal
225225
*/
226226
public static $EXTN_PATTERNS_FOR_MATCHING;
227+
228+
// Regular expression of valid global-number-digits for the phone-context parameter, following the
229+
// syntax defined in RFC3966.
230+
protected static $RFC3966_VISUAL_SEPARATOR = "[\\-\\.\\(\\)]?";
231+
protected static $RFC3966_PHONE_DIGIT;
232+
protected static $RFC3966_GLOBAL_NUMBER_DIGITS;
233+
234+
// Regular expression of valid domainname for the phone-context parameter, following the syntax
235+
// defined in RFC3966.
236+
protected static $ALPHANUM;
237+
protected static $RFC3966_DOMAINLABEL;
238+
protected static $RFC3966_TOPLABEL;
239+
protected static $RFC3966_DOMAINNAME;
240+
227241
protected static $EXTN_PATTERN;
228242
protected static $VALID_PHONE_NUMBER_PATTERN;
229243
protected static $MIN_LENGTH_PHONE_NUMBER_PATTERN;
@@ -346,6 +360,7 @@ protected function __construct(MetadataSourceInterface $metadataSource, $country
346360
$this->matcherAPI = RegexBasedMatcher::create();
347361
static::initExtnPatterns();
348362
static::initExtnPattern();
363+
static::initRFC3966Patterns();
349364
static::$PLUS_CHARS_PATTERN = '[' . static::PLUS_CHARS . ']+';
350365
static::$SEPARATOR_PATTERN = '[' . static::VALID_PUNCTUATION . ']+';
351366
static::$CAPTURING_DIGIT_PATTERN = '(' . static::DIGITS . ')';
@@ -474,7 +489,7 @@ public static function initExtnPatterns()
474489
* @param int $maxLength
475490
* @return string
476491
*/
477-
private static function extnDigits($maxLength)
492+
protected static function extnDigits($maxLength)
478493
{
479494
return '(' . self::DIGITS . '{1,' . $maxLength . '})';
480495
}
@@ -569,6 +584,17 @@ protected static function initExtnPattern()
569584
static::$EXTN_PATTERN = '/(?:' . static::$EXTN_PATTERNS_FOR_PARSING . ')$/' . static::REGEX_FLAGS;
570585
}
571586

587+
protected static function initRFC3966Patterns()
588+
{
589+
static::$RFC3966_PHONE_DIGIT = '(' . static::DIGITS . '|' . static::$RFC3966_VISUAL_SEPARATOR . ')';
590+
static::$RFC3966_GLOBAL_NUMBER_DIGITS = "^\\" . static::PLUS_SIGN . static::$RFC3966_PHONE_DIGIT . "*" . static::DIGITS . static::$RFC3966_PHONE_DIGIT . "*$";
591+
592+
static::$ALPHANUM = static::VALID_ALPHA . static::DIGITS;
593+
static::$RFC3966_DOMAINLABEL = '[' . static::$ALPHANUM . "]+((\\-)*[" . static::$ALPHANUM . "])*";
594+
static::$RFC3966_TOPLABEL = '[' . static::VALID_ALPHA . "]+((\\-)*[" . static::$ALPHANUM . "])*";
595+
static::$RFC3966_DOMAINNAME = "^(" . static::$RFC3966_DOMAINLABEL . "\\.)*" . static::$RFC3966_TOPLABEL . "\\.?$";
596+
}
597+
572598
protected static function initValidPhoneNumberPatterns()
573599
{
574600
static::initExtnPatterns();
@@ -1776,6 +1802,60 @@ protected function parseHelper($numberToParse, $defaultRegion, $keepRawInput, $c
17761802
$phoneNumber->setNationalNumber($normalizedNationalNumber);
17771803
}
17781804

1805+
/**
1806+
* Extracts the value of the phone-context parameter of numberToExtractFrom where the index of
1807+
* ";phone-context=" is the parameter indexOfPhoneContext, following the syntax defined in
1808+
* RFC3966.
1809+
*
1810+
* @param string $numberToExtractFrom
1811+
* @param int|false $indexOfPhoneContext
1812+
* @return string|null the extracted string (possibly empty), or null if no phone-context parameter is found.
1813+
*/
1814+
protected function extractPhoneContext($numberToExtractFrom, $indexOfPhoneContext)
1815+
{
1816+
// If no phone-context parameter is present
1817+
if ($indexOfPhoneContext === false) {
1818+
return null;
1819+
}
1820+
1821+
$phoneContextStart = $indexOfPhoneContext + strlen(static::RFC3966_PHONE_CONTEXT);
1822+
// If phone-context parameter is empty
1823+
if ($phoneContextStart >= mb_strlen($numberToExtractFrom)) {
1824+
return '';
1825+
}
1826+
1827+
$phoneContextEnd = strpos($numberToExtractFrom, ';', $phoneContextStart);
1828+
// If phone-context is not the last parameter
1829+
if ($phoneContextEnd !== false) {
1830+
return substr($numberToExtractFrom, $phoneContextStart, $phoneContextEnd - $phoneContextStart);
1831+
}
1832+
1833+
return substr($numberToExtractFrom, $phoneContextStart);
1834+
}
1835+
1836+
/**
1837+
* Returns whether the value of phoneContext follows the syntax defined in RFC3966.
1838+
*
1839+
* @param string|null $phoneContext
1840+
* @return bool
1841+
*/
1842+
protected function isPhoneContextValid($phoneContext)
1843+
{
1844+
if ($phoneContext === null) {
1845+
return true;
1846+
}
1847+
1848+
if ($phoneContext === '') {
1849+
return false;
1850+
}
1851+
1852+
$numberDigitsPattern = '/' . static::$RFC3966_GLOBAL_NUMBER_DIGITS . '/' . static::REGEX_FLAGS;
1853+
$domainNamePattern = '/' . static::$RFC3966_DOMAINNAME . '/' . static::REGEX_FLAGS;
1854+
1855+
// Does phone-context value match pattern of global-number-digits or domainname
1856+
return preg_match($numberDigitsPattern, $phoneContext) || preg_match($domainNamePattern, $phoneContext);
1857+
}
1858+
17791859
/**
17801860
* Returns a new phone number containing only the fields needed to uniquely identify a phone
17811861
* number, rather than any fields that capture the context in which the phone number was created.
@@ -1805,32 +1885,32 @@ protected static function copyCoreFieldsOnly(PhoneNumber $phoneNumberIn)
18051885
* written in RFC3966; otherwise extract a possible number out of it and write to nationalNumber.
18061886
* @param string $numberToParse
18071887
* @param string $nationalNumber
1888+
* @throws NumberParseException
18081889
*/
18091890
protected function buildNationalNumberForParsing($numberToParse, &$nationalNumber)
18101891
{
18111892
$indexOfPhoneContext = strpos($numberToParse, static::RFC3966_PHONE_CONTEXT);
1812-
if ($indexOfPhoneContext !== false) {
1813-
$phoneContextStart = $indexOfPhoneContext + mb_strlen(static::RFC3966_PHONE_CONTEXT);
1893+
$phoneContext = $this->extractPhoneContext($numberToParse, $indexOfPhoneContext);
1894+
1895+
if (!$this->isPhoneContextValid($phoneContext)) {
1896+
throw new NumberParseException(NumberParseException::NOT_A_NUMBER, 'The phone-context valid is invalid.');
1897+
}
1898+
1899+
if ($phoneContext !== null) {
18141900
// If the phone context contains a phone number prefix, we need to capture it, whereas domains
18151901
// will be ignored.
1816-
if ($phoneContextStart < (strlen($numberToParse) - 1)
1817-
&& substr($numberToParse, $phoneContextStart, 1) == static::PLUS_SIGN) {
1902+
1903+
if (strpos($phoneContext, self::PLUS_SIGN) === 0) {
18181904
// Additional parameters might follow the phone context. If so, we will remove them here
1819-
// because the parameters after phone context are not important for parsing the
1820-
// phone number.
1821-
$phoneContextEnd = strpos($numberToParse, ';', $phoneContextStart);
1822-
if ($phoneContextEnd > 0) {
1823-
$nationalNumber .= substr($numberToParse, $phoneContextStart, $phoneContextEnd - $phoneContextStart);
1824-
} else {
1825-
$nationalNumber .= substr($numberToParse, $phoneContextStart);
1826-
}
1905+
// because the parameters after phone context are not important for parsing the phone
1906+
// number.
1907+
$nationalNumber .= $phoneContext;
18271908
}
18281909

18291910
// Now append everything between the "tel:" prefix and the phone-context. This should include
18301911
// the national number, an optional extension or isdn-subaddress component. Note we also
18311912
// handle the case when "tel:" is missing, as we have seen in some of the phone number inputs.
18321913
// In that case, we append everything from the beginning.
1833-
18341914
$indexOfRfc3966Prefix = strpos($numberToParse, static::RFC3966_PREFIX);
18351915
$indexOfNationalNumber = ($indexOfRfc3966Prefix !== false) ? $indexOfRfc3966Prefix + strlen(static::RFC3966_PREFIX) : 0;
18361916
$nationalNumber .= substr(

src/carrier/data/en/220.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
22051 => 'QCell',
1818
22052 => 'QCell',
1919
22053 => 'QCell',
20+
22054 => 'QCell',
2021
22058 => 'QCell',
2122
22059 => 'QCell',
2223
2206 => 'Comium',

src/carrier/data/en/60.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
601171 => 'Celecom',
262262
6011710 => 'DiGi',
263263
6011711 => 'DiGi',
264+
6011720 => 'Celecom',
264265
6011721 => 'Celecom',
265266
6011722 => 'Maxis',
266267
6011723 => 'Maxis',

src/data/PhoneNumberMetadata_BL.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
return array (
1515
'generalDesc' =>
1616
array (
17-
'NationalNumberPattern' => '(?:590|(?:69|80)\\d|976)\\d{6}',
17+
'NationalNumberPattern' => '590\\d{6}|(?:69|80|9\\d)\\d{7}',
1818
'PossibleLength' =>
1919
array (
2020
0 => 9,
@@ -88,7 +88,7 @@
8888
),
8989
'voip' =>
9090
array (
91-
'NationalNumberPattern' => '976[01]\\d{5}',
91+
'NationalNumberPattern' => '9(?:395|76[018])\\d{5}',
9292
'ExampleNumber' => '976012345',
9393
'PossibleLength' =>
9494
array (

src/data/PhoneNumberMetadata_GF.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
return array (
1515
'generalDesc' =>
1616
array (
17-
'NationalNumberPattern' => '(?:[56]94|80\\d|976)\\d{6}',
17+
'NationalNumberPattern' => '[56]94\\d{6}|(?:80|9\\d)\\d{7}',
1818
'PossibleLength' =>
1919
array (
2020
0 => 9,
@@ -88,7 +88,7 @@
8888
),
8989
'voip' =>
9090
array (
91-
'NationalNumberPattern' => '976\\d{6}',
91+
'NationalNumberPattern' => '9(?:396|76\\d)\\d{5}',
9292
'ExampleNumber' => '976012345',
9393
'PossibleLength' =>
9494
array (
@@ -151,7 +151,7 @@
151151
'format' => '$1 $2 $3 $4',
152152
'leadingDigitsPatterns' =>
153153
array (
154-
0 => '[569]',
154+
0 => '[56]|97',
155155
),
156156
'nationalPrefixFormattingRule' => '0$1',
157157
'domesticCarrierCodeFormattingRule' => '',
@@ -163,7 +163,7 @@
163163
'format' => '$1 $2 $3 $4',
164164
'leadingDigitsPatterns' =>
165165
array (
166-
0 => '8',
166+
0 => '[89]',
167167
),
168168
'nationalPrefixFormattingRule' => '0$1',
169169
'domesticCarrierCodeFormattingRule' => '',

src/data/PhoneNumberMetadata_GM.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
),
3737
'mobile' =>
3838
array (
39-
'NationalNumberPattern' => '(?:[23679]\\d|5[0-389])\\d{5}',
39+
'NationalNumberPattern' => '(?:[23679]\\d|5[0-489])\\d{5}',
4040
'ExampleNumber' => '3012345',
4141
'PossibleLength' =>
4242
array (

src/data/PhoneNumberMetadata_GP.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
return array (
1515
'generalDesc' =>
1616
array (
17-
'NationalNumberPattern' => '(?:590|(?:69|80)\\d|976)\\d{6}',
17+
'NationalNumberPattern' => '590\\d{6}|(?:69|80|9\\d)\\d{7}',
1818
'PossibleLength' =>
1919
array (
2020
0 => 9,
@@ -88,7 +88,7 @@
8888
),
8989
'voip' =>
9090
array (
91-
'NationalNumberPattern' => '976[01]\\d{5}',
91+
'NationalNumberPattern' => '9(?:395|76[018])\\d{5}',
9292
'ExampleNumber' => '976012345',
9393
'PossibleLength' =>
9494
array (

src/data/PhoneNumberMetadata_KW.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
),
3939
'mobile' =>
4040
array (
41-
'NationalNumberPattern' => '(?:41\\d\\d|5(?:(?:[05]\\d|1[0-7]|6[56])\\d|2(?:22|5[25])|7(?:55|77)|88[58])|6(?:(?:0[034679]|5[015-9]|6\\d)\\d|1(?:00|11|66)|222|3[36]3|444|7(?:0[013-9]|[67]\\d)|888|9(?:[069]\\d|3[039]))|9(?:(?:0[09]|22|[4679]\\d|8[057-9])\\d|1(?:1[01]|99)|3(?:00|33)|5(?:00|5\\d)))\\d{4}',
41+
'NationalNumberPattern' => '(?:41\\d\\d|5(?:(?:[05]\\d|1[0-7]|6[56])\\d|2(?:22|5[25])|7(?:55|77)|88[58])|6(?:(?:0[034679]|5[015-9]|6\\d)\\d|1(?:00|11|66)|222|3[36]3|444|7(?:0[013-9]|[67]\\d)|888|9(?:[069]\\d|3[039]))|9(?:(?:0[09]|[4679]\\d|8[057-9])\\d|1(?:1[01]|99)|2(?:00|2\\d)|3(?:00|3[03])|5(?:00|5\\d)))\\d{4}',
4242
'ExampleNumber' => '50012345',
4343
'PossibleLength' =>
4444
array (

src/data/PhoneNumberMetadata_MF.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
return array (
1515
'generalDesc' =>
1616
array (
17-
'NationalNumberPattern' => '(?:590|(?:69|80)\\d|976)\\d{6}',
17+
'NationalNumberPattern' => '590\\d{6}|(?:69|80|9\\d)\\d{7}',
1818
'PossibleLength' =>
1919
array (
2020
0 => 9,
@@ -88,7 +88,7 @@
8888
),
8989
'voip' =>
9090
array (
91-
'NationalNumberPattern' => '976[01]\\d{5}',
91+
'NationalNumberPattern' => '9(?:395|76[018])\\d{5}',
9292
'ExampleNumber' => '976012345',
9393
'PossibleLength' =>
9494
array (

src/data/PhoneNumberMetadata_MY.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
),
4545
'mobile' =>
4646
array (
47-
'NationalNumberPattern' => '1(?:1888[689]|4400|8(?:47|8[27])[0-4])\\d{4}|1(?:0(?:[23568]\\d|4[0-6]|7[016-9]|9[0-8])|1(?:[1-5]\\d\\d|6(?:0[5-9]|[1-9]\\d)|7(?:[0134]\\d|2[1-9]|5[0-6]))|(?:[269]\\d|[37][1-9]|4[235-9])\\d|5(?:31|9\\d\\d)|8(?:1[23]|[236]\\d|4[06]|5(?:46|[7-9])|7[016-9]|8[01]|9[0-8]))\\d{5}',
47+
'NationalNumberPattern' => '1(?:1888[689]|4400|8(?:47|8[27])[0-4])\\d{4}|1(?:0(?:[23568]\\d|4[0-6]|7[016-9]|9[0-8])|1(?:[1-5]\\d\\d|6(?:0[5-9]|[1-9]\\d)|7(?:[0-4]\\d|5[0-6]))|(?:[269]\\d|[37][1-9]|4[235-9])\\d|5(?:31|9\\d\\d)|8(?:1[23]|[236]\\d|4[06]|5(?:46|[7-9])|7[016-9]|8[01]|9[0-8]))\\d{5}',
4848
'ExampleNumber' => '123456789',
4949
'PossibleLength' =>
5050
array (

0 commit comments

Comments
 (0)