From: Aleš Mrázek Date: Tue, 29 Jul 2025 06:36:08 +0000 (+0200) Subject: datamodel/types: reduced validation strictness for DomainName X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0ebebba77980fa0de2b00dcbef687c03425f3e2;p=thirdparty%2Fknot-resolver.git datamodel/types: reduced validation strictness for DomainName --- diff --git a/doc/_static/config.schema.json b/doc/_static/config.schema.json index 0670f35e3..88e11901d 100644 --- a/doc/_static/config.schema.json +++ b/doc/_static/config.schema.json @@ -793,12 +793,12 @@ "type": "array", "items": { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" } }, { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" } ] } @@ -1003,12 +1003,12 @@ "type": "array", "items": { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" } }, { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" } ], "description": "Subtree(s) to forward." @@ -1081,7 +1081,7 @@ "string", "null" ], - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$", + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$", "description": "Hostname of the Forward server.", "default": null }, @@ -1251,7 +1251,7 @@ "properties": { "origin": { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$", + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$", "description": "Origin for the imported data. Cache prefilling is only supported for the root zone ('.')." }, "url": { @@ -1402,7 +1402,7 @@ ], "items": { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" }, "description": "List of domain names representing negative trust-anchors. (RFC 7646)", "default": null @@ -1687,7 +1687,7 @@ }, { "type": "string", - "pattern": "(?=^.{,253}\\.?$)(^(?!\\.)((?!-)\\.?[a-zA-Z0-9-]{,62}[a-zA-Z0-9])+\\.?$)|^\\.$" + "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$" } ] }, diff --git a/python/knot_resolver/datamodel/types/types.py b/python/knot_resolver/datamodel/types/types.py index 946e2b13e..fb22169ef 100644 --- a/python/knot_resolver/datamodel/types/types.py +++ b/python/knot_resolver/datamodel/types/types.py @@ -143,15 +143,18 @@ class DomainName(StrBase): """ _punycode: str + # fmt: off _re = re.compile( r"(?=^.{,253}\.?$)" # max 253 chars - r"(^(?!\.)" # do not start name with dot - r"((?!-)" # do not start label with hyphen - r"\.?[a-zA-Z0-9-]{,62}" # max 63 chars in label - r"[a-zA-Z0-9])+" # do not end label with hyphen - r"\.?$)" # end with or without '.' + r"(^" + # do not allow hyphen at the start and at the end of label + r"(?!-)[^.]{,62}[^.-]" # max 63 chars in label; except dot + r"(\.(?!-)[^.]{,62}[^.-])*" # start with dot; max 63 chars in label except dot + r"\.?" # end with or without dot + r"$)" r"|^\.$" # allow root-zone ) + # fmt: on def __init__(self, source_value: Any, object_path: str = "/") -> None: super().__init__(source_value, object_path) diff --git a/tests/manager/datamodel/types/test_custom_types.py b/tests/manager/datamodel/types/test_custom_types.py index 5614fd0a2..744e9b132 100644 --- a/tests/manager/datamodel/types/test_custom_types.py +++ b/tests/manager/datamodel/types/test_custom_types.py @@ -153,6 +153,7 @@ def test_escaped_str_invalid(val: Any): [ ".", "example.com", + "_8443._https.example.com.", "this.is.example.com.", "test.example.com", "test-example.com", @@ -174,7 +175,9 @@ def test_domain_name_valid(val: str): [ "test.example..com.", "-example.com", + "-test.example.net", "test-.example.net", + "test.-example.net", ".example.net", _rand_domain(64), _rand_domain(1, 128),