Files
bikini-patchwork/tests/test_stress_matrix.py
T
2026-06-04 04:36:39 -05:00

125 lines
3.9 KiB
Python

from __future__ import annotations
import random
import subprocess
import sys
from pathlib import Path
import tempfile
import textwrap
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from patchwork import Obfuscator
GENERATED_SEEDS = [3, 11, 29, 101, 1009]
OBFUSCATION_SEEDS = [5, 17, 257]
def run(path: Path) -> str:
result = subprocess.run([sys.executable, str(path)], capture_output=True, text=True, timeout=20)
if result.returncode != 0:
raise RuntimeError(f"{path} exited {result.returncode}\nstderr:\n{result.stderr}")
return result.stdout
def generated_program(seed: int) -> str:
rng = random.Random(seed)
numbers = [rng.randint(-5000, 5000) for _ in range(16)]
strings = [f"s{idx}_{rng.randrange(1 << 20):x}" for idx in range(6)]
pairs = [(rng.randint(-20, 20), rng.randint(-20, 20)) for _ in range(8)]
return textwrap.dedent(
f"""
from __future__ import annotations
NUMBERS = {numbers!r}
STRINGS = {strings!r}
PAIRS = {pairs!r}
def fold(values):
acc = 0
for idx, value in enumerate(values):
if idx % 3 == 0:
acc ^= value
elif idx % 3 == 1:
acc += value << (idx % 5)
else:
acc -= value >> (idx % 4)
return acc
def classify(item):
match item:
case (0, y):
return f"zero:{{y}}"
case (x, y) if x == y:
return f"same:{{x}}"
case (x, y):
return f"pair:{{x + y}}"
case _:
return "other"
def closure(base):
state = base
def inner(delta):
nonlocal state
state = (state + delta) ^ (delta << 2)
return state
return inner
def run():
fn = closure(7)
print("fold", fold(NUMBERS))
print("strings", "|".join(s[::-1] for s in STRINGS))
print("pairs", [classify(pair) for pair in PAIRS])
print("closure", [fn(x) for x in range(6)])
print("bytes", bytes(range(8)).hex())
if __name__ == "__main__":
run()
"""
).lstrip()
def check_source(source: str, *, label: str, seed: int, **kwargs) -> None:
obf_source = Obfuscator(seed=seed, **kwargs).obfuscate(source)
with tempfile.TemporaryDirectory() as raw:
directory = Path(raw)
src_path = directory / f"{label}.py"
obf_path = directory / f"{label}_obf.py"
src_path.write_text(source, encoding="utf-8")
obf_path.write_text(obf_source, encoding="utf-8")
expected = run(src_path)
actual = run(obf_path)
if actual != expected:
raise AssertionError(f"{label} seed={seed} mismatch\n--- expected ---\n{expected}--- actual ---\n{actual}")
def main() -> int:
failures = 0
matrix = [
{},
{"lazy_funcs": False},
{"anti_debug": False},
{"rename": False},
{"encrypt_strings": False},
{"opaque_predicates": False, "junk_branches": False},
]
for generated_seed in GENERATED_SEEDS:
source = generated_program(generated_seed)
for obfuscation_seed in OBFUSCATION_SEEDS:
for options in matrix:
label = f"generated_{generated_seed}_{obfuscation_seed}_{len(options)}"
try:
check_source(source, label=label, seed=obfuscation_seed, **options)
print(f"ok: {label} {options}")
except Exception as exc:
failures += 1
print(f"FAIL: {label} {options}: {exc}")
print(f"\n{failures} failures" if failures else "\nstress matrix all good")
return 1 if failures else 0
if __name__ == "__main__":
raise SystemExit(main())