#!/usr/bin/env python3 """Generate a "lying" zip-bomb test fixture for CorbelPurge. This crafts a ZIP archive where the central directory declares a small uncompressed size (100 bytes) but the actual decompressed content is much larger (1 MiB). This simulates a malicious archive that tries to bypass size-header-based caps. The ZIP format is hand-crafted (not via the `zip` library) so we can lie about the size. The structure is: [Local File Header][file data][Central Directory][End of Central Dir] Each file header has both a "compressed size" and "uncompressed size" field. We set the central directory's "uncompressed size" to 100, but write 1 MiB of actual data. A naive reader that trusts the header would only allocate 100 bytes; a streaming reader counts actual bytes and detects the lie. """ import struct import zlib from pathlib import Path FIXTURES_DIR = Path(__file__).parent.parent / "tests" / "fixtures" FIXTURES_DIR.mkdir(parents=True, exist_ok=True) def make_lying_zip_bomb(): """Create a ZIP where the declared uncompressed size is 100 bytes but the actual decompressed content is 1 MiB. The ZIP is structurally valid (decompressors can read it) but the central directory lies about the size. CorbelPurge's streaming `read_with_cap` should detect this by counting actual bytes. """ # The actual content: 1 MiB of 'A' characters. actual_content = b"A" * (1024 * 1024) # Compress it with DEFLATE. compressed = zlib.compress(actual_content, 9) # The "lie": declare the uncompressed size as 100 bytes. declared_uncompressed_size = 100 declared_compressed_size = len(compressed) # we don't lie about this # CRC32 of the actual content (the decompressor will compute this # and we need to match it for the CRC check to pass). crc = zlib.crc32(actual_content) & 0xFFFFFFFF # --- Local File Header --- local_header = struct.pack( "