From: XhmikosR Date: Sun, 5 Jul 2026 14:20:53 +0000 (+0300) Subject: Reject domains with invalid characters in normalize_rule X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=c912e408e69107d2a138af43f80bd2c5aec2ce13;p=stevenblack-hosts.git Reject domains with invalid characters in normalize_rule --- diff --git a/testUpdateHostsFile.py b/testUpdateHostsFile.py index 9de043aff..3f0ac45d1 100644 --- a/testUpdateHostsFile.py +++ b/testUpdateHostsFile.py @@ -837,7 +837,7 @@ class TestNormalizeRule(BaseStdout): def test_no_match(self): kwargs = dict(targetip="0.0.0.0", keep_domain_comments=False) - # Note: "Bare"- Domains are accepted. IP are excluded. + # Note: "Bare"- Domains are accepted. IPs are excluded. for rule in [ "128.0.0.1", "::1", @@ -847,6 +847,11 @@ class TestNormalizeRule(BaseStdout): "0.0.0.0 https", "0.0.0.0 https..", "0.0.0.0 foo.", + "0.0.0.0 cm076410.tw1.ru]", + "0.0.0.0 example.com[", + "0.0.0.0 exa mple.com", + "0.0.0.0 -example.com", + "0.0.0.0 example-.com", ]: self.assertEqual(normalize_rule(rule, **kwargs), (None, None)) @@ -934,7 +939,8 @@ class TestNormalizeRule(BaseStdout): "foo.bar.edu", "www.example-foo.bar.edu", "www.example-3045.foobar.com", - "www.example.xn--p1ai" + "www.example.xn--p1ai", + "philadelphia_cbslocal.us.intellitxt.com", ): expected = (rule, "0.0.0.0 " + rule + "\n") diff --git a/updateHostsFile.py b/updateHostsFile.py index 2a79fcef5..a29b2a21b 100755 --- a/updateHostsFile.py +++ b/updateHostsFile.py @@ -1022,6 +1022,33 @@ def remove_dups_and_excl(mergefile, exclusionregexes, outputfile=None): return finalfile +# Dot-separated labels of [a-z0-9_-], hyphens not at label ends, at least two +# labels. Expects a lowercased hostname. +VALID_DOMAIN_REGEX = re.compile( + r"(?:[a-z0-9_]|[a-z0-9_][a-z0-9_-]*[a-z0-9_])" + r"(?:\.(?:[a-z0-9_]|[a-z0-9_][a-z0-9_-]*[a-z0-9_]))+" +) + + +def is_valid_domain(hostname): + """ + Check whether a lowercased hostname looks like a valid domain name. + + Parameters + ---------- + hostname : str + The hostname to validate. + + Returns + ------- + valid : bool + Whether the hostname only contains characters allowed in a domain + name and has a valid label structure. + """ + + return bool(VALID_DOMAIN_REGEX.fullmatch(hostname)) + + def normalize_rule(rule, targetip, keep_domain_comments): """ Standardize and format the rule string provided. @@ -1144,33 +1171,19 @@ def normalize_rule(rule, targetip, keep_domain_comments): if ( is_ip(hostname) or re.search(static_ip_regex, hostname) - or "." not in hostname - or ".." in hostname - or "." in hostname[-1] - or "/" in hostname - or ":" in hostname + or not is_valid_domain(hostname) ): # Example: 0.0.0.0 127.0.0.1 - # If the hostname is: - # - an IP - or looks like it, - # - doesn't contain dots, or - # - contains repeated dots, - # - ends in a dot, or - # - contains a slash, or - # - contains a colon, - # - contains an underscore, - # we don't want to normalize it. + # If the hostname is an IP (or looks like one), or isn't a valid + # domain (bad characters, no dot, repeated/trailing dots, slash, + # colon, ...), we don't want to normalize it. return belch_unwanted(rule) return normalize_response(hostname, suffix) - if ( - not re.search(static_ip_regex, split_rule[0]) - and ":" not in split_rule[0] - and ".." not in split_rule[0] - and "/" not in split_rule[0] - and "." in split_rule[0] + if not re.search(static_ip_regex, split_rule[0]) and is_valid_domain( + split_rule[0].lower() ): # Deny anything that looks like an IP; doesn't container dots or INVALID.