91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
"""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")
|