"""Pure input validation and supported host-list line formats.""" import ipaddress import re from urllib.parse import urlparse def should_ignore_domain(domain): return domain.startswith(".") or any( ch in domain for ch in ["~", "=", "$", "'", "^", "_", ">", "<", ":"] ) def should_ignore_line(line): return any(sym in line for sym in ["<", ">", "##", "###", "div", "span"]) def is_valid_domain(domain): return bool(re.compile(r"^(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$").match(domain)) def convert_host_line(line: str, target_ip: str): # szybkie odrzucenia if not line: return None line = line.strip() if not line or line.startswith(("!", "#", "/", ";")): return None for sep in (" #", " ;"): idx = line.find(sep) if idx != -1: line = line[:idx].rstrip() if not line: return None m = re.match(r"^\|\|([a-z0-9.-]+)\^", line, re.IGNORECASE) if m: domain = m.group(1).strip(".") if not should_ignore_domain(domain) and is_valid_domain(domain): return f"{target_ip} {domain}" return None parts = line.split() if len(parts) >= 2 and ( re.match(r"^\d{1,3}(?:\.\d{1,3}){3}$", parts[0]) or ":" in parts[0] ): domain = parts[1].strip().split("#", 1)[0].strip().strip(".") if not should_ignore_domain(domain) and is_valid_domain(domain): return f"{target_ip} {domain}" return None m = re.match(r"^(?:address|server)=/([a-z0-9.-]+)/", line, re.IGNORECASE) if m: domain = m.group(1).strip(".") if not should_ignore_domain(domain) and is_valid_domain(domain): return f"{target_ip} {domain}" return None token = parts[0].split("#", 1)[0].strip().strip(".") if token and not should_ignore_domain(token) and is_valid_domain(token): return f"{target_ip} {token}" return None def validate_and_normalize_url(url): url = (url or "").strip() # prosta sanity-check: usuĊ„ CR/LF if any(c in url for c in ("\r", "\n")): raise ValueError("Invalid characters in URL") parsed = urlparse(url) if not parsed.scheme: url = f"https://{url}" parsed = urlparse(url) # akceptuj tylko http/https if parsed.scheme not in {"http", "https"}: raise ValueError(f"Unsupported scheme: {parsed.scheme}") if not parsed.netloc: raise ValueError("Missing host in URL") return parsed.geturl() def validate_ip(value: str) -> str: v = (value or "").strip() try: return str(ipaddress.ip_address(v)) except Exception: raise ValueError("Invalid IP address")