diff --git a/src/validators/hostname.py b/src/validators/hostname.py index 96fca00..ad415e1 100644 --- a/src/validators/hostname.py +++ b/src/validators/hostname.py @@ -34,13 +34,13 @@ def _port_validator(value: str): if value.count("]:") == 1: # with ipv6 host_seg, port_seg = value.rsplit(":", 1) - if _port_regex().match(f":{port_seg}"): + if _port_regex().fullmatch(f":{port_seg}"): return host_seg.lstrip("[").rstrip("]") if value.count(":") == 1: # with ipv4 or simple hostname host_seg, port_seg = value.rsplit(":", 1) - if _port_regex().match(f":{port_seg}"): + if _port_regex().fullmatch(f":{port_seg}"): return host_seg return None @@ -120,7 +120,7 @@ def _matches_simple_hostname(host: str): # hostname, not only on the dotted names handled by `domain()`. if rfc_1034 and host.endswith("."): host = host[:-1] - return _simple_hostname_regex().match(host) + return _simple_hostname_regex().fullmatch(host) if may_have_port and (host_seg := _port_validator(value)): return ( diff --git a/tests/test_hostname.py b/tests/test_hostname.py index 1fe2468..df54b02 100644 --- a/tests/test_hostname.py +++ b/tests/test_hostname.py @@ -109,3 +109,19 @@ def test_returns_true_on_hostname_within_rfc_length_limits(value: str): def test_returns_failed_validation_on_hostname_beyond_rfc_limits(value: str): """Test returns failed validation on hostname beyond RFC limits.""" assert isinstance(hostname(value), ValidationError) + + +@pytest.mark.parametrize( + "value", + [ + "ubuntu-pc\n", + "ubuntu-pc:443\n", + "example.com:443\n", + "127.0.0.1:22\n", + "[::1]:22\n", + "[dead:beef:0:0:0:0000:42:1]:5731\n", + ], +) +def test_rejects_trailing_newline_in_hostnames_and_ports(value: str): + """Test rejects trailing newline in hostnames and ports.""" + assert isinstance(hostname(value), ValidationError)