"""Exercise arbitrary bounded prefix lengths, outer/nested streaming and guards.""" import io import hashlib import json import struct import subprocess import tempfile import zipfile import zlib from pathlib import Path ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / 'build/save-prefix' OUT.mkdir(parents=True, exist_ok=True) runtime = ROOT / 'third_party/wabt/wasm2c' subprocess.run(['xcrun', 'clang', '-O2', '-DWASM_RT_USE_MMAP=0', '-DWASM_RT_MEMCHECK_BOUNDS_CHECK=1', '-I'+str(ROOT/'runtime'), '-I'+str(ROOT/'build/version'), '-I'+str(runtime), str(ROOT/'tests/save_prefix_probe.c'), str(ROOT/'runtime/save_header.c'), str(ROOT/'runtime/version_bridge.c'), str(ROOT/'build/version/factorio_version.c'), str(runtime/'wasm-rt-impl.c'), str(runtime/'wasm-rt-mem-impl.c'), '-lz', '-o', str(OUT/'probe')], check=True) def archive(payload, method, streaming=False): class NonSeeking(io.BytesIO): def seek(self, *args): raise OSError('streaming') output = NonSeeking() if streaming else io.BytesIO() with zipfile.ZipFile(output, 'w', compression=method) as z: z.writestr('fixture/level.dat0', zlib.compress(payload)) return output.getvalue() checks = 0 def probe(data, length, expected, status=0): global checks with tempfile.TemporaryDirectory() as directory: path = Path(directory)/'fixture.zip' path.write_bytes(data) result = subprocess.run([str(OUT/'probe'),str(path),str(length)],capture_output=True,text=True) assert result.returncode == (1 if status else 0), result.stderr report = json.loads(result.stdout) assert report['status'] == status, report assert bytes.fromhex(report['prefix_hex']) == expected checks += 1 payload = struct.pack('<4HB',2,0,77,0,0) + bytes(range(256))*300 for method in (zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED): for streaming in (False, True): data = archive(payload,method,streaming) for length in (1,8,9,10,33,4095,4096,4097,65536,len(payload)): probe(data,length,payload[:length]) probe(data,len(payload)+1,b'',6) probe(data,0,b'',7) probe(data,1024*1024+1,b'',7) probe(b'invalid',33,b'',2) incompressible = struct.pack('<4HB',2,0,77,0,0) incompressible += b''.join(hashlib.sha256(i.to_bytes(4,'little')).digest() for i in range(2048)) for method in (zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED): for streaming in (False,True): data=archive(incompressible,method,streaming) for length in (4097,len(incompressible)): probe(data,length,incompressible[:length]) over_budget=b''.join(hashlib.sha256(i.to_bytes(4,'little')).digest() for i in range(32768)) probe(archive(over_budget,zipfile.ZIP_STORED),1024*1024,b'',7) print(f'PASS: {checks} bounded prefix cases, exact bytes, output guards and failure atomicity') (OUT/'verification.json').write_text(json.dumps({'status':'pass','cases':checks, 'scope':'synthetic archives; bounded prefix only'},indent=2)+'\n')