Fix all 47 bugs — hardened attack engine, UI/UX, proxy, CAPTCHA, config

This commit is contained in:
Dr Jones
2026-05-22 18:21:27 -07:00
parent 1152a937f7
commit bef3de1245
25 changed files with 868 additions and 150 deletions

View File

@@ -2,26 +2,92 @@
File I/O utilities for reading/writing password lists and proxy lists.
"""
from pathlib import Path
from typing import List, Optional
from typing import Generator, Iterator, List, Optional
from config import PASSWORDS_FILE, PROXIES_FILE, VALID_PROXIES_FILE
def save_passwords(passwords: List[str], filepath: Optional[Path] = None, append: bool = True):
"""Save password list to file. Appends by default."""
def save_passwords(passwords: List[str], filepath: Optional[Path] = None,
append: bool = True, dedupe: bool = False):
"""
Save password list to file.
Args:
passwords: list of passwords to save.
filepath: destination path (default: PASSWORDS_FILE).
append: append to existing file when True; overwrite when False.
dedupe: when True, load existing file, union with new passwords,
deduplicate (preserving order), then write back. (bug #18)
"""
path = filepath or PASSWORDS_FILE
mode = "a" if append else "w"
with open(path, mode, encoding="utf-8") as f:
for pwd in passwords:
f.write(pwd + "\n")
if dedupe:
existing = load_passwords(path)
merged = list(dict.fromkeys(existing + passwords))
with open(path, "w", encoding="utf-8") as f:
for pwd in merged:
f.write(pwd + "\n")
else:
mode = "a" if append else "w"
with open(path, mode, encoding="utf-8") as f:
for pwd in passwords:
f.write(pwd + "\n")
def load_passwords(filepath: Optional[Path] = None) -> List[str]:
"""Load passwords from file, stripping whitespace and removing empties."""
"""
Load passwords from file, stripping whitespace and removing empties.
Deduplicates while preserving order. (bug #30)
"""
path = filepath or PASSWORDS_FILE
if not path.exists():
return []
with open(path, "r", encoding="utf-8") as f:
return [line.strip() for line in f if line.strip()]
lines = [line.strip() for line in f if line.strip()]
# bug #30: deduplicate, preserve order
return list(dict.fromkeys(lines))
def stream_passwords(
filepath: Optional[Path] = None,
chunk_size: int = 1000,
) -> Generator[List[str], None, None]:
"""
Streaming generator that yields lists of passwords in chunks.
Avoids loading the full wordlist into RAM. (bug #4)
Usage:
for chunk in stream_passwords():
process(chunk)
"""
path = filepath or PASSWORDS_FILE
if not path.exists():
return
chunk: List[str] = []
seen = set()
with open(path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and line not in seen:
seen.add(line)
chunk.append(line)
if len(chunk) >= chunk_size:
yield chunk
chunk = []
if chunk:
yield chunk
def count_passwords(filepath: Optional[Path] = None) -> int:
"""Count deduplicated passwords without loading them all into RAM."""
path = filepath or PASSWORDS_FILE
if not path.exists():
return 0
seen = set()
with open(path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line:
seen.add(line)
return len(seen)
def save_proxies(proxies: List[str], filepath: Optional[Path] = None):
@@ -42,8 +108,19 @@ def load_proxies(filepath: Optional[Path] = None) -> List[str]:
def save_valid_proxies(proxies: List[str]):
"""Save validated proxies to their dedicated file."""
save_proxies(proxies, VALID_PROXIES_FILE)
"""
Save validated proxies, merging with any existing file entries.
Deduplicates before writing so committed proxies are never lost. (bug #12)
"""
path = VALID_PROXIES_FILE
existing: List[str] = []
if path.exists():
with open(path, "r", encoding="utf-8") as f:
existing = [line.strip() for line in f if line.strip()]
merged = list(dict.fromkeys(existing + proxies))
with open(path, "w", encoding="utf-8") as f:
for proxy in merged:
f.write(proxy + "\n")
def load_valid_proxies() -> List[str]: