Skip to content

Commit c0f3576

Browse files
kenballusmiss-islington
authored andcommitted
pythongh-96035: Make urllib.parse.urlparse reject non-numeric ports (pythonGH-98273)
Co-authored-by: Jelle Zijlstra <[email protected]> (cherry picked from commit 6f15ca8) Co-authored-by: Ben Kallus <[email protected]>
1 parent ace6611 commit c0f3576

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

Lib/test/test_urlparse.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,13 +653,16 @@ def test_attributes_bad_port(self):
653653
"""Check handling of invalid ports."""
654654
for bytes in (False, True):
655655
for parse in (urllib.parse.urlsplit, urllib.parse.urlparse):
656-
for port in ("foo", "1.5", "-1", "0x10"):
656+
for port in ("foo", "1.5", "-1", "0x10", "-0", "1_1", " 1", "1 ", "६"):
657657
with self.subTest(bytes=bytes, parse=parse, port=port):
658658
netloc = "www.example.net:" + port
659659
url = "http://" + netloc
660660
if bytes:
661-
netloc = netloc.encode("ascii")
662-
url = url.encode("ascii")
661+
if netloc.isascii() and port.isascii():
662+
netloc = netloc.encode("ascii")
663+
url = url.encode("ascii")
664+
else:
665+
continue
663666
p = parse(url)
664667
self.assertEqual(p.netloc, netloc)
665668
with self.assertRaises(ValueError):
@@ -1195,6 +1198,7 @@ def test_splitnport(self):
11951198
self.assertEqual(splitnport('127.0.0.1', 55), ('127.0.0.1', 55))
11961199
self.assertEqual(splitnport('parrot:cheese'), ('parrot', None))
11971200
self.assertEqual(splitnport('parrot:cheese', 55), ('parrot', None))
1201+
self.assertEqual(splitnport('parrot: +1_0 '), ('parrot', None))
11981202

11991203
def test_splitquery(self):
12001204
# Normal cases are exercised by other tests; ensure that we also

Lib/urllib/parse.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,11 @@ def hostname(self):
167167
def port(self):
168168
port = self._hostinfo[1]
169169
if port is not None:
170-
try:
171-
port = int(port, 10)
172-
except ValueError:
173-
message = f'Port could not be cast to integer value as {port!r}'
174-
raise ValueError(message) from None
175-
if not ( 0 <= port <= 65535):
170+
if port.isdigit() and port.isascii():
171+
port = int(port)
172+
else:
173+
raise ValueError(f"Port could not be cast to integer value as {port!r}")
174+
if not (0 <= port <= 65535):
176175
raise ValueError("Port out of range 0-65535")
177176
return port
178177

@@ -1125,15 +1124,15 @@ def splitnport(host, defport=-1):
11251124
def _splitnport(host, defport=-1):
11261125
"""Split host and port, returning numeric port.
11271126
Return given default port if no ':' found; defaults to -1.
1128-
Return numerical port if a valid number are found after ':'.
1127+
Return numerical port if a valid number is found after ':'.
11291128
Return None if ':' but not a valid number."""
11301129
host, delim, port = host.rpartition(':')
11311130
if not delim:
11321131
host = port
11331132
elif port:
1134-
try:
1133+
if port.isdigit() and port.isascii():
11351134
nport = int(port)
1136-
except ValueError:
1135+
else:
11371136
nport = None
11381137
return host, nport
11391138
return host, defport
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix bug in :func:`urllib.parse.urlparse` that causes certain port numbers
2+
containing whitespace, underscores, plus and minus signs, or non-ASCII digits to be
3+
incorrectly accepted.

0 commit comments

Comments
 (0)