Skip to content

Commit 846bc86

Browse files
Reject out-of-range URL ports (must be 0–65535)
URL.from_text() and URL() accepted ports like -1 and 65536/99999 after int() conversion. Validate the TCP/UDP port range on parse and construction so callers get URLParseError/ValueError instead of serializing illegal authorities.
1 parent 978f2e6 commit 846bc86

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

‎src/hyperlink/_url.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,8 @@ def __init__(
10351035
)
10361036
self._fragment = _textcheck("fragment", fragment)
10371037
self._port = _typecheck("port", port, int, NoneType)
1038+
if self._port is not None and not (0 <= self._port <= 65535):
1039+
raise ValueError("port must be in range 0-65535, not %r" % (self._port,))
10381040
self._rooted = _typecheck("rooted", rooted, bool)
10391041
self._userinfo = _textcheck("userinfo", userinfo, "/?#@")
10401042

@@ -1413,6 +1415,10 @@ def from_text(cls, text):
14131415
if not port: # TODO: excessive?
14141416
raise URLParseError("port must not be empty: %r" % au_text)
14151417
raise URLParseError("expected integer for port, not %r" % port)
1418+
if not (0 <= port <= 65535):
1419+
raise URLParseError(
1420+
"port must be in range 0-65535, not %r" % (port,)
1421+
)
14161422

14171423
scheme = gs["scheme"] or u""
14181424
fragment = gs["fragment"] or u""

‎src/hyperlink/test/test_url.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,3 +1493,25 @@ def test_idna_corners(self):
14931493
assert (
14941494
URL.from_text(text).to_uri().get_decoded_url().host == "example.com"
14951495
)
1496+
1497+
1498+
class OutOfRangePortTests(object):
1499+
def test_from_text_rejects_out_of_range_port(self):
1500+
from hyperlink import URL, URLParseError
1501+
for bad in ("http://ex.com:-1", "http://ex.com:65536", "http://ex.com:99999"):
1502+
try:
1503+
URL.from_text(bad)
1504+
except URLParseError:
1505+
pass
1506+
else:
1507+
raise AssertionError("expected URLParseError for %r" % (bad,))
1508+
1509+
def test_ctor_rejects_out_of_range_port(self):
1510+
from hyperlink import URL
1511+
for bad in (-1, 65536, 99999):
1512+
try:
1513+
URL(scheme=u"http", host=u"ex.com", port=bad)
1514+
except ValueError:
1515+
pass
1516+
else:
1517+
raise AssertionError("expected ValueError for port %r" % (bad,))

0 commit comments

Comments
 (0)