Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/validators/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ def domain(
if not value:
return False

if consider_tld and not _IanaTLD.check(value.rstrip(".").rsplit(".", 1)[-1].upper()):
return False

try:
if _relies_on_idna_mapping(value):
return False
Expand All @@ -114,6 +111,11 @@ def domain(
# ref: RFC 1035, presentation form is limited to 253 characters
return False

# IANA lists IDN TLDs in their ASCII (punycode) form,
# so look up the encoded TLD, not the raw one.
if consider_tld and not _IanaTLD.check(encoded.rstrip(".").rsplit(".", 1)[-1].upper()):
return False

return not re.search(r"\s|__+", value) and re.match(
# First character of the domain
rf"^(?:[a-z0-9{service_record}]"
Expand Down
4 changes: 4 additions & 0 deletions tests/test_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def test_returns_true_on_valid_domain(value: str, rfc_1034: bool, rfc_2782: bool
("somerandomexample.onion", True, False, False),
# delegated 2026-07-23
("somerandomexample.web", True, False, False),
("пример.рф", True, False, False),
("пример.рф.", True, True, False),
("例子.中国", True, False, False),
],
)
def test_returns_true_on_valid_top_level_domain(
Expand Down Expand Up @@ -104,6 +107,7 @@ def test_returns_failed_validation_on_invalid_domain(value: str, rfc_1034: bool,
("somerandomexample.xn-n-fiqs8s", True, False, False),
# retired from the root zone
("somerandomexample.goo", True, False, False),
("пример.рфы", True, False, False),
],
)
def test_returns_failed_validation_invalid_top_level_domain(
Expand Down
26 changes: 26 additions & 0 deletions tests/test_hostname.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,29 @@ def test_returns_failed_validation_on_idna_mapped_lookalike_hostname(value: str)
def test_returns_failed_validation_on_ipv4_lookalike_hostname(value: str):
"""Test returns failed validation on dotted names whose last label is non-ASCII digits."""
assert isinstance(hostname(value), ValidationError)


@pytest.mark.parametrize(
"value",
[
"example.com:443",
"xn--e1afmkfd.xn--p1ai",
"пример.рф",
"пример.рф:8080",
],
)
def test_returns_true_on_valid_top_level_domain_hostname(value: str):
"""Test returns true on hostname with a TLD allowed by IANA."""
assert hostname(value, consider_tld=True)


@pytest.mark.parametrize(
"value",
[
"example.flat:443",
"пример.рфы",
],
)
def test_returns_failed_validation_on_invalid_top_level_domain_hostname(value: str):
"""Test returns failed validation on hostname with a TLD not allowed by IANA."""
assert isinstance(hostname(value, consider_tld=True), ValidationError)
26 changes: 26 additions & 0 deletions tests/test_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,29 @@ def test_returns_failed_validation_on_idna_mapped_lookalike_url(value: str):
def test_returns_failed_validation_on_ipv4_lookalike_url(value: str, private: Optional[bool]):
"""Test returns failed validation on hosts that only look like an IPv4 address."""
assert isinstance(url(value, private=private), ValidationError)


@pytest.mark.parametrize(
"value",
[
"https://example.com/path",
"https://xn--e1afmkfd.xn--p1ai/",
"https://пример.рф/",
"http://例子.中国:8080/index.html",
],
)
def test_returns_true_on_valid_top_level_domain_url(value: str):
"""Test returns true on url with a TLD allowed by IANA."""
assert url(value, consider_tld=True)


@pytest.mark.parametrize(
"value",
[
"https://example.flat/",
"https://пример.рфы/",
],
)
def test_returns_failed_validation_on_invalid_top_level_domain_url(value: str):
"""Test returns failed validation on url with a TLD not allowed by IANA."""
assert isinstance(url(value, consider_tld=True), ValidationError)
Loading