Skip to content

Commit 2bdf952

Browse files
committed
Merge code changes from upstream r431
1 parent fb6dc76 commit 2bdf952

File tree

6 files changed

+93
-73
lines changed

6 files changed

+93
-73
lines changed

python/phonenumbers/phonenumberutil.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
_MAX_LENGTH_FOR_NSN = 16
7272
# The maximum length of the country calling code.
7373
_MAX_LENGTH_COUNTRY_CODE = 3
74+
# We don't allow input strings for parsing to be longer than 250 chars. This
75+
# prevents malicious input from overflowing the regular-expression engine.
76+
_MAX_INPUT_STRING_LENGTH = 250
7477
# Region-code for the unknown region.
7578
UNKNOWN_REGION = u"ZZ"
7679
# The set of regions that share country calling code 1.
@@ -2234,6 +2237,9 @@ def parse(number, region=None, keep_raw_input=False,
22342237
if number is None:
22352238
raise NumberParseException(NumberParseException.NOT_A_NUMBER,
22362239
"The phone number supplied was None.")
2240+
elif len(number) > _MAX_INPUT_STRING_LENGTH:
2241+
raise NumberParseException(NumberParseException.TOO_LONG,
2242+
"The string supplied was too long to parse.")
22372243
raw_number = number
22382244
# Extract a possible number from the string passed in (this strips leading
22392245
# characters that could not be the start of a phone number.)

python/tests/asyoutypetest.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,21 @@
1616
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1717
# See the License for the specific language governing permissions and
1818
# limitations under the License.
19-
import unittest
20-
2119
from phonenumbers import AsYouTypeFormatter
2220
from phonenumbers import PhoneMetadata, PhoneNumberDesc, NumberFormat
2321
# Access internal functions of phonenumberutil.py
2422
from phonenumbers import phonenumberutil
25-
from .phonenumberutiltest import insert_test_metadata, reinstate_real_metadata
23+
from .testmetadatatest import TestMetadataTestCase
2624

2725

28-
class AsYouTypeFormatterTest(unittest.TestCase):
26+
class AsYouTypeFormatterTest(TestMetadataTestCase):
2927
"""Unit tests for AsYouTypeFormatter.java
3028
31-
Note that these tests use the metadata contained in the files in
32-
tests/data, not the normal metadata files, so should not be used for
33-
regression test purposes - these tests are illustrative only and test
34-
functionality.
29+
Note that these tests use the test metadata, not the normal metadata file,
30+
so should not be used for regression test purposes - these tests are
31+
illustrative only and test functionality.
3532
"""
3633

37-
def setUp(self):
38-
insert_test_metadata()
39-
40-
def tearDown(self):
41-
reinstate_real_metadata()
42-
4334
def testInvalidRegion(self):
4435
formatter = AsYouTypeFormatter("ZZ")
4536
self.assertEqual("+", formatter.input_digit('+'))

python/tests/phonenumbermatchertest.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
from phonenumbers import PhoneNumberMatch, PhoneNumberMatcher, Leniency
2424
from phonenumbers import PhoneNumber, phonenumberutil
25-
from .phonenumberutiltest import insert_test_metadata, reinstate_real_metadata
25+
from .testmetadatatest import TestMetadataTestCase
2626

2727

2828
class PhoneNumberMatchTest(unittest.TestCase):
@@ -196,19 +196,13 @@ def __str__(self):
196196
]
197197

198198

199-
class PhoneNumberMatcherTest(unittest.TestCase):
199+
class PhoneNumberMatcherTest(TestMetadataTestCase):
200200
"""Tests for PhoneNumberMatcher.
201201
202202
This only tests basic functionality based on test metadata. See
203203
testphonenumberutil.py for the origin of the test data.
204204
"""
205205

206-
def setUp(self):
207-
insert_test_metadata()
208-
209-
def tearDown(self):
210-
reinstate_real_metadata()
211-
212206
# See PhoneNumberUtilTest.testParseNationalNumber().
213207
def testFindNationalNumber(self):
214208
# same cases as in testParseNationalNumber
@@ -679,6 +673,18 @@ def testMaxMatchesMixed(self):
679673

680674
self.assertEqual(expected, actual)
681675

676+
def testNonPlusPrefixedNumbersNotFoundForInvalidRegion(self):
677+
# Does not start with a "+", we won't match it.
678+
matcher = PhoneNumberMatcher("1 456 764 156", "ZZ")
679+
self.assertFalse(matcher.has_next())
680+
try:
681+
matcher.next()
682+
self.fail("Violation of the Iterator contract.")
683+
except Exception:
684+
# Success
685+
pass
686+
self.assertFalse(matcher.has_next())
687+
682688
def testEmptyIteration(self):
683689
matcher = PhoneNumberMatcher("", "ZZ")
684690
self.assertFalse(matcher.has_next())

python/tests/phonenumberutiltest.py

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
# See the License for the specific language governing permissions and
1818
# limitations under the License.
1919
import sys
20-
import unittest
2120

2221
import phonenumbers
2322
from phonenumbers import PhoneNumber, PhoneMetadata
@@ -26,18 +25,8 @@
2625
from phonenumbers import ValidationResult, NumberFormat, CountryCodeSource
2726
# Access internal functions of phonenumberutil.py
2827
from phonenumbers import phonenumberutil
28+
from .testmetadatatest import TestMetadataTestCase
2929

30-
# Override library metadata with the test metadata.
31-
REAL_REGION_METADATA = PhoneMetadata.region_metadata
32-
REAL_CC_TO_RC = phonenumberutil.COUNTRY_CODE_TO_REGION_CODE
33-
34-
PhoneMetadata.region_metadata = {}
35-
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = {}
36-
37-
# Import the test data; this will re-populate the
38-
# PhoneMetadata.region_metadata map
39-
from .testdata import _COUNTRY_CODE_TO_REGION_CODE as TEST_CC_TO_RC
40-
TEST_REGION_METADATA = PhoneMetadata.region_metadata
4130

4231
if sys.version_info >= (3, 0):
4332
# Python 3 has unlimited-precision int, so no 'L' suffix
@@ -49,20 +38,6 @@
4938
_UP = 'u'
5039

5140

52-
def reinstate_real_metadata():
53-
"""Reinstate real phone number metadata"""
54-
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = REAL_CC_TO_RC
55-
PhoneMetadata.region_metadata = REAL_REGION_METADATA
56-
57-
58-
def insert_test_metadata():
59-
"""Insert test metadata into library"""
60-
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = TEST_CC_TO_RC
61-
PhoneMetadata.region_metadata = TEST_REGION_METADATA
62-
63-
# Reinstate the real metadata so any importers of this module are not affected
64-
reinstate_real_metadata()
65-
6641
# Set up some test numbers to re-use.
6742
ALPHA_NUMERIC_NUMBER = FrozenPhoneNumber(country_code=1, national_number=80074935247L)
6843
AR_MOBILE = FrozenPhoneNumber(country_code=54, national_number=91187654321L)
@@ -101,20 +76,13 @@ def insert_test_metadata():
10176
XY_NUMBER = FrozenPhoneNumber(country_code=999, national_number=1234567890L)
10277

10378

104-
class PhoneNumberUtilTest(unittest.TestCase):
79+
class PhoneNumberUtilTest(TestMetadataTestCase):
10580
"""Unit tests for phonenumbers/__init__.py
10681
107-
Note that these tests use the metadata contained in the files in
108-
tests/data, not the normal metadata files, so should not be used for
109-
regression test purposes - these tests are illustrative only and test
110-
functionality.
82+
Note that these tests use the test metadata, not the normal metadata file,
83+
so should not be used for regression test purposes - these tests are
84+
illustrative only and test functionality.
11185
"""
112-
def setUp(self):
113-
insert_test_metadata()
114-
115-
def tearDown(self):
116-
reinstate_real_metadata()
117-
11886
def testSupportedRegions(self):
11987
self.assertTrue(len(phonenumbers.SUPPORTED_REGIONS) > 0)
12088
# Python version extra test
@@ -1015,13 +983,9 @@ def testIsValidForRegion(self):
1015983
invalidNumber.country_code = 3923
1016984
invalidNumber.national_number = 2366L
1017985
self.assertFalse(phonenumbers.is_valid_number_for_region(invalidNumber, "ZZ"))
1018-
invalidNumber.country_code = 3923
1019-
invalidNumber.national_number = 2366L
1020986
self.assertFalse(phonenumbers.is_valid_number_for_region(invalidNumber, "001"))
1021987
invalidNumber.country_code = 0
1022-
invalidNumber.national_number = 2366L
1023988
self.assertFalse(phonenumbers.is_valid_number_for_region(invalidNumber, "001"))
1024-
invalidNumber.country_code = 0
1025989
self.assertFalse(phonenumbers.is_valid_number_for_region(invalidNumber, "ZZ"))
1026990

1027991
# Python version extra test
@@ -1550,6 +1514,28 @@ def testParseNumberWithAlphaCharacters(self):
15501514
self.assertEqual(premiumNumber, phonenumbers.parse("0900 332 600A5", "NZ"))
15511515
self.assertEqual(premiumNumber, phonenumbers.parse("0900 a332 600A5", "NZ"))
15521516

1517+
def testParseMaliciousInput(self):
1518+
# Lots of leading + signs before the possible number.
1519+
maliciousNumber = '+' * 6000 + "12222-33-244 extensioB 343+"
1520+
try:
1521+
phonenumbers.parse(maliciousNumber, "US")
1522+
self.fail("This should not parse without throwing an exception %s" % maliciousNumber)
1523+
except NumberParseException, e:
1524+
# Expected this exception.
1525+
self.assertEqual(e.error_type,
1526+
NumberParseException.TOO_LONG,
1527+
msg="Wrong error type stored in exception.")
1528+
1529+
maliciousNumberWithAlmostExt = "200" * 350 + " extensiOB 345"
1530+
try:
1531+
phonenumbers.parse(maliciousNumberWithAlmostExt, "US")
1532+
self.fail("This should not parse without throwing an exception %s" % maliciousNumberWithAlmostExt)
1533+
except NumberParseException, e:
1534+
# Expected this exception.
1535+
self.assertEqual(e.error_type,
1536+
NumberParseException.TOO_LONG,
1537+
msg="Wrong error type stored in exception.")
1538+
15531539
def testParseWithInternationalPrefixes(self):
15541540
self.assertEqual(US_NUMBER, phonenumbers.parse("+1 (650) 253-0000", "NZ"))
15551541
self.assertEqual(INTERNATIONAL_TOLL_FREE, phonenumbers.parse("011 800 1234 5678", "US"))

python/tests/shortnumberutiltest.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,13 @@
1717
# See the License for the specific language governing permissions and
1818
# limitations under the License.
1919

20-
import unittest
21-
2220
from phonenumbers import connects_to_emergency_number, is_emergency_number
23-
from .phonenumberutiltest import insert_test_metadata, reinstate_real_metadata
21+
from .testmetadatatest import TestMetadataTestCase
2422

2523

26-
class ShortNumberUtilTest(unittest.TestCase):
24+
class ShortNumberUtilTest(TestMetadataTestCase):
2725
"""Unit tests for shortnumberutil.py"""
2826

29-
def setUp(self):
30-
insert_test_metadata()
31-
32-
def tearDown(self):
33-
reinstate_real_metadata()
34-
3527
def testConnectsToEmergencyNumber_US(self):
3628
self.assertTrue(connects_to_emergency_number("911", "US"))
3729
self.assertTrue(connects_to_emergency_number("119", "US"))

python/tests/testmetadatatest.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import unittest
2+
3+
from phonenumbers import PhoneMetadata
4+
from phonenumbers import phonenumberutil
5+
6+
# Override library metadata with the test metadata.
7+
REAL_REGION_METADATA = PhoneMetadata.region_metadata
8+
REAL_CC_TO_RC = phonenumberutil.COUNTRY_CODE_TO_REGION_CODE
9+
10+
PhoneMetadata.region_metadata = {}
11+
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = {}
12+
13+
# Import the test data; this will re-populate the
14+
# PhoneMetadata.region_metadata map
15+
from .testdata import _COUNTRY_CODE_TO_REGION_CODE as TEST_CC_TO_RC
16+
TEST_REGION_METADATA = PhoneMetadata.region_metadata
17+
18+
19+
def reinstate_real_metadata():
20+
"""Reinstate real phone number metadata"""
21+
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = REAL_CC_TO_RC
22+
PhoneMetadata.region_metadata = REAL_REGION_METADATA
23+
24+
25+
def insert_test_metadata():
26+
"""Insert test metadata into library"""
27+
phonenumberutil.COUNTRY_CODE_TO_REGION_CODE = TEST_CC_TO_RC
28+
PhoneMetadata.region_metadata = TEST_REGION_METADATA
29+
30+
# Reinstate the real metadata so any importers of this module are not affected
31+
reinstate_real_metadata()
32+
33+
34+
class TestMetadataTestCase(unittest.TestCase):
35+
def setUp(self):
36+
insert_test_metadata()
37+
38+
def tearDown(self):
39+
reinstate_real_metadata()

0 commit comments

Comments
 (0)