Packaging
Current Zstandard executable bundles, validation and proposed compression presets.
How the prototype bundle works
The BSIS builder creates a self-contained setup executable by appending a Zstandard-compressed file payload to an existing native Windows PE runtime.
BSIS-Hello-Setup.exe
- Native Windows runtime
Compressed Zstandard stream
- Payload magic and manifest length
- Versioned package manifest
- File content, in manifest order
- FooterMagic, offset, length and SHA-256
The builder requires a runtime compiled for Windows; a Linux binary is not interchangeable with a Windows setup executable.
Build and inspect
cargo build --release -p bsis
cargo run -p bsis -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Hello-Setup.exe
.\BSIS-Hello-Setup.exe inspect
The embedded manifest enumerates each file's relative path, byte length and SHA-256 checksum. The footer identifies the compressed stream and its digest. Ordinary inspection checks that compressed digest and the manifest; optional deep inspection also verifies each uncompressed embedded file hash.
Choose the Zstandard compression level
The prototype currently uses Zstandard only, but the builder supports selecting how aggressively it compresses files with --compression-level. The default is 3 for compatibility with existing build commands.
cargo run -p bsis --locked -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Fast-Setup.exe --compression-level 1
cargo run -p bsis --locked -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Small-Setup.exe --compression-level 9
| Zstandard level | Typical tradeoff |
|---|---|
| 1 | Faster compression, often a larger setup file |
| 3 (default) | General-purpose build |
| 9 | More compression work, potentially a smaller setup file |
| 19 | Highest currently accepted setting; much slower for many inputs |
Allowed levels are 1 through 19, inclusive. Invalid levels are rejected before packaging. Higher levels do not guarantee a smaller file for every data set, and they do not change the installed payload's contents or integrity verification. The entire executable contains the same version 1 Zstandard stream and SHA-256 footer regardless of the chosen level.
The level is a CLI flag on the build command, not a bsis.json configuration field. LZMA2, LZ4 and named codec presets are still planned, not implemented.
Deep verification without installing
.\BSIS-Hello-Setup.exe inspect --deep
.\BSIS-Hello-Setup.exe inspect --deep --json
This streams the full Zstandard payload and checks every file against its manifest SHA-256, including its declared size and absence of extra trailing data. It catches payload changes even if someone recomputes the outer compressed footer digest but leaves the manifest unchanged.
No files are extracted or installed. Deep mode uses CPU to decompress the full package. A malicious actor able to change both the manifest and payload could create internally consistent checksums, so this is not publisher authentication.
Extraction and commit
- Validate the package metadata and target path.
- Accept a new or existing empty destination directory. Reject nonempty folders and unsupported filesystem links.
- Create a fresh staging directory beside the target.
- Decompress and write each file, verifying its hash.
- Store the installation receipt and rename the completed stage into place. For an existing empty folder, temporarily move that folder aside and attempt restoration if the commit fails.
If extraction fails before the final rename, the temporary stage is removed. This does not provide upgrade rollback or protect against all concurrent filesystem attacks.
Integrity and limits
The runtime checks the compressed package digest and hashes extracted files against manifest entries. Invalid destination paths, conflicting names, unsupported source links and mismatched hashes are rejected.
The current Rust manifest imposes limits on manifest bytes, file count and total declared payload size. These are defensive bounds, not proof of production readiness.
SHA-256 is not a signature: a malicious publisher could generate a different executable with internally consistent checksums. Authenticode signing and verification are future work.
Future compression choices
| Proposed preset | Codec | Status |
|---|---|---|
| Maximum | LZMA2 | Not implemented |
| Balanced | Zstandard | Current implemented codec; selectable levels 1–19 |
| Fast | LZ4 | Not implemented |
The binary layout is provisional. Do not build tooling that assumes long-term compatibility with the current overlay or footer format.
For the manifest fields see Configuration; for install and uninstall safeguards see Security model.
Preflight a package
Before writing a Setup.exe, developers can run the read-only plan --config bsis.json [--json] command to preview sorted destination paths, file sizes and SHA-256 hashes. It catches invalid Windows destinations, missing/linked sources and collisions before compression.
Package preflight documents the command and JSON report. A plan is a snapshot, not a build cache: BSIS independently re-checks files while packaging, because they can change after the preview.