Skip to content

Commit 0750b62

Browse files
committed
Accept trailing dot on simple hostnames with rfc_1034
hostname('ie', rfc_1034=True) is valid, but hostname('ie.', rfc_1034=True) was rejected. The RFC 1034 trailing dot was only handled by domain() (for dotted names); a simple, single-label hostname went through _simple_hostname_regex(), which does not allow a trailing dot, so it failed. Strip an optional trailing dot before the simple-hostname check when rfc_1034 is set, so a single-label hostname behaves consistently with and without the dot. The dot is still rejected when rfc_1034 is False. Refs #442
1 parent 70de324 commit 0750b62

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

src/validators/hostname.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,25 @@ def hostname(
113113
if not value:
114114
return False
115115

116+
def _matches_simple_hostname(host: str):
117+
if not maybe_simple:
118+
return False
119+
# A trailing dot (RFC 1034) is also valid on a simple, single-label
120+
# hostname, not only on the dotted names handled by `domain()`.
121+
if rfc_1034 and host.endswith("."):
122+
host = host[:-1]
123+
return _simple_hostname_regex().match(host)
124+
116125
if may_have_port and (host_seg := _port_validator(value)):
117126
return (
118-
(_simple_hostname_regex().match(host_seg) if maybe_simple else False)
127+
_matches_simple_hostname(host_seg)
119128
or domain(host_seg, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782)
120129
or (False if skip_ipv4_addr else ipv4(host_seg, cidr=False, private=private))
121130
or (False if skip_ipv6_addr else ipv6(host_seg, cidr=False))
122131
)
123132

124133
return (
125-
(_simple_hostname_regex().match(value) if maybe_simple else False)
134+
_matches_simple_hostname(value)
126135
or domain(value, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782)
127136
or (False if skip_ipv4_addr else ipv4(value, cidr=False, private=private))
128137
or (False if skip_ipv6_addr else ipv6(value, cidr=False))

tests/test_hostname.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
("this-pc", False, False),
1616
("lab-01a-notebook:404", False, False),
1717
("4-oh-4", False, False),
18+
# simple, single-label hostname w/ trailing dot (RFC 1034); see #442
19+
("this-pc.", True, False),
20+
("ie.", True, False),
1821
# hostname w/ optional ports
1922
("example.com:4444", False, False),
2023
("kräuter.com.", True, False),
@@ -45,6 +48,8 @@ def test_returns_true_on_valid_hostname(value: str, rfc_1034: bool, rfc_2782: bo
4548
("this-pc-is-sh*t", False, False),
4649
("lab-01a-note._com_.com:404", False, False),
4750
("4-oh-4:@.com", False, False),
51+
# trailing dot is only allowed with rfc_1034; see #442
52+
("this-pc.", False, False),
4853
# bad (hostname w/ optional ports)
4954
("example.com:-4444", False, False),
5055
("xn----gtbspbbmkef.xn--p1ai:65538", False, False),

0 commit comments

Comments
 (0)