Vitali Web Tools — local archive decoder (build vwt1, 2026-09-08) This is an app-owned Emscripten build of libarchive 3.8.9, with one clearly identified local patch. It is not an unchanged upstream binary. Components: - libarchive 3.8.9: BSD notices, plus per-file notices in libarchive-source-notices.txt. See libarchive-COPYING.txt. The BLAKE2 reference code is used under its offered CC0 1.0 option. - liblzma from XZ Utils 5.8.3: BSD Zero Clause; see liblzma-0BSD.txt and xz-COPYING.txt. No XZ command-line utilities are linked. - zlib 1.3.2: see zlib-LICENSE.txt. Emscripten's pinned zlib port is used. - bzip2 1.0.8: see bzip2-LICENSE.txt. Compiled directly from current official sources; Emscripten's obsolete bzip2 1.0.6 port is NOT used. - Emscripten 6.0.9 runtime: see emscripten-LICENSE.txt. - musl / compiler-rt runtime portions: see musl-COPYRIGHT.txt and compiler-rt-LICENSE.txt. Original library source archives are provided in sources/ with SHA-256 in SOURCES.json. The app-owned wrapper archive-native.c and exact local patch libarchive-rar4-crc.patch are provided there too. Local change: the stored RAR4 sequential-read EOF shortcut in libarchive 3.8.9 can bypass its terminal CRC check. The patch checks the complete sequential CRC before returning EOF. The wrapper exposes no seeking. Tests damage actual stored payload bytes and assert rejection; supported unchanged payloads are independently compared byte-for-byte or by SHA-256. Runtime restrictions: read-only ZIP/RAR4/RAR5/7z. No filesystem, arbitrary URL, external decompression process, password interface, persistent storage, archive recursion or content execution is exposed. ZIP uses the existing app-owned structural parser and fflate; the native decoder handles RAR/7z. Only selected entries are exported. Solid archives can require internal decoding of preceding blocks while listing or reading later entries. Limits: 30 MiB compressed input; 256 entries; 16 MiB each; 64 MiB cumulative declared/selected bytes; 20 path levels; declared ratio 200:1 (ZIP per entry, RAR/7z total declared size versus input size); 20-second dedicated-worker wall-time limit; each worker reuses one native instance with a 256 MiB maximum WASM linear memory. JavaScript/file buffers and browser overhead are additional. There is no promise that the entire browser uses only 256 MiB. Unsupported: encrypted/password-protected archives, split/multi-volume archives, self-extracting archives, ZIP64, ZIP codecs other than stored/DEFLATE, legacy non-ASCII ZIP names without UTF-8, symlinks/hardlinks, special/sparse files, unsafe/ambiguous paths, and archives exceeding these limits. No malware or universal archive-compatibility certification is claimed. Build reproduction: sources/build-archive-wasm.sh is the distributed copy of apps/vitaliwebtools/scripts/build-archive-wasm.sh in the source repository. Run that repository script from this application: VWT_ARCHIVE_PYTHON=/path/to/python3.10-or-newer bash scripts/build-archive-wasm.sh full It installs the pinned portable SDK only in this app's ignored tmp/archive-build, checks source hashes, compiles the dependencies and wrapper, and writes only this app's public/vendor/archive files. Needs git, curl-capable SDK installer, tar, make, patch, rg and a native host supported by Emscripten; no Docker, system installation or shell-profile modification is performed. bash scripts/build-archive-wasm.sh verify-link relinks the built static libraries into an ignored directory and byte-compares both artifacts. The complete script and verify-link have actually been run. An independent clean-host rebuild has not been performed. Actual tests: Node/Vitest uses the real vendored WASM, public libarchive test fixtures, independent macOS bsdtar 3.5.3 / libarchive 3.7.4 decoding references, independent fflate reopening of selection ZIP output, and hostile fixtures in terminable Node workers. Browser/hardware validation is tracked separately by the parent application's release record; these engine tests do not establish browser support, live publication or user traffic.