My VAXstations now have Zip 3.0 and UnZip 6.0,
the last official Info-ZIP releases, with the security fixes they never
got. It was built on the VAX itself, with the compiler and build procedures that come with
OpenVMS. These ZIP files keep everything that makes a VMS file a VMS file: with -V, a variable-length text file, a
fixed-512 file and an indexed file go into a zip file and come out again with the same organisation, record
format, key definitions and creation date. The kit is a BACKUP saveset with a DCL installer and a DCL uninstaller.
Claude Code did most of the hard work.
Downloads, with SHA-256 sums in SHA256SUMS.TXT:
- INFOZIP_VAX_20261013B.BCK
(6.2 MB, SHA-256
e26ddf5c5c20c5a2e894e4153b308bf4f32b67a3e2b9ae3dbf65d1d1529eca8d): the kit to install, and its file list INFOZIP_VAX_20261013B_LIST.LIS. - INFOZIP_INSTALL.COM, INFOZIP_UNINSTALL.COM and INFOZIP_SETUP.COM (each user runs it once per login).
- README.TXT (installing, uninstalling, what is in the kit) and SOURCES.TXT (where every file comes from).
- The licence: INFOZIP_LICENSE_UNZIP60.TXT and INFOZIP_LICENSE_ZIP30.TXT.
- infozip-vms-vax-sources-20261013B.zip
(2.6 MB): the two original archives (
unzip60.tar.gz,zip30.tar.gz), Debian’s source descriptions and patch series, every patch as a diff (kept apart from the originals),PATCHES.TXT, and the hashes of every file before and after patching. The patched sources are also in the saveset itself.
Why bother with Zip on a VAX
Every file I move to the VAXen typically goes as a zip, and every file I want off them has to travel as something. VMS
has BACKUP, which keeps everything but is understood only by VMS. Zip is understood by everything: the
laptop, a phone, the web. With the Info-ZIP -V option a zip file is also a faithful VMS backup of a file,
and still opens with any unzip program.
What is built
Info-ZIP’s two programs are plain C with DCL build procedures (BUILD_UNZIP.COM, BUILD_ZIP.COM) that
know about VAX and the Compaq C compiler: no make, no MMS, no configure script. Their own notes list “VMS VAX
V7.3, DEC/Compaq C” as tested. So the build procedures and the VMS code needed no change; the only source changes are
the patches listed below, and the work was to put it on a real machine in a way that could be repeated:
- The sources are the real ones. Zip 3.0 (5 July 2008) and UnZip 6.0 (20 April 2009) from SourceForge, checked against the hashes in Debian’s signed source descriptions.
- 34 patches, 32 of them Debian’s fixes for the two programs (see below), one-line marker patches of ours
(the Info-ZIP licence says an altered version must say so, so
unzip -vnow reads “altered build with security patches”), and nothing else. Each patch keeps its author’s header. - No bzip2 (there is no bzip2 library on the machine) and no Zip64 (the VAX build has no 64-bit file support): the archives are limited to 2 GB and to deflate, which is what everything uses.
- Bundles instead of a tarball. The VAX has no
tarorunzipyet; that is what is being built. The two source trees travel as ASCII bundle files (!!!FILE name ... !!!END) that a 50-line C program splits. - Two command styles. Both programs exist in two versions each:
UNZIP -l file.zipas on Linux, andUNZIP_VMS /LIST file.zipwith VMS qualifiers.ZIPINFOisUNZIP -Z. On a VAX, DCL makes unquoted arguments lower case and no C run-time switch changes that, so-V(keep VMS attributes) and-Pmust be written in double quotes:ZIP "-V" ....
The security fixes, and what is not fixed
Debian’s unzip 6.0-31 and zip 3.0-16 carry the fixes that the 2009 releases never got. All the ones that
touch code that runs on VMS are in the kit (the full table, with each patch’s own description, is in
PATCHES.TXT): UnZip CVE-2014-8139, -8140, -8141, -9636, -9913, CVE-2015-7696, -7697, CVE-2016-9844,
CVE-2018-1000035, CVE-2019-13232 (five patches, by Mark Adler, against overlapping-entry “zip bombs”),
CVE-2022-0529 and -0530 (by Steven Schweda, a long-time Info-ZIP VMS contributor; his name is on the patch),
three 2026 fixes Debian made this year, and for Zip CVE-2018-13410 (a buffer overflow with -T -TT), a buffer
overflow with Unicode file names, a format-string fix and a command-injection fix.
Not fixed: CVE-2021-4217, a null-pointer dereference in UnZip’s Unicode string handling. No patch exists for
it; Debian rates it “unimportant”. The post says so; do not run these programs on archives from people you do
not trust any more than you would the originals.
(M) The build, with Compaq C V6.4-005 on the real VAXstation 4000/90: UnZip 6.0 gave one informational
message (%CC-I-RIGHTSHIFTOVR, extract.c: a shift by 32 of a 32-bit value that only a Zip64 entry could reach),
Zip 3.0 none.
Examples
RUN_TESTS.COM makes 48 checks and prints PASS n of n; it needs no privilege, works in its own scratch
directory and removes it. Expected values never come from Info-ZIP:
| What | How it is checked |
|---|---|
A zip made by Info-ZIP 3.0 on Linux and one made by Python’s zipfile (10 files each, a nested directory, stored and deflated entries, a 319 KB text, a 100 KB run of zeros, random binary) | UNZIP -t, extraction, then every file zipped again and its length and CRC-32 compared with the values computed by Python’s zlib.crc32 |
-a on a 3000-line text whose line lengths run from 0 to 199, with and without a final line end, and on CR LF text | no record lost (3000 records, 2 records of 12 characters) |
A variable-length text file, a fixed-512 file and an indexed file, through ZIP -V and UNZIP -V | organisation, record format, record size, size in blocks, creation date equal; DIFFERENCES finds nothing; CHECKSUM equal; the indexed file is indexed again. The control: without -V the fixed-512 file comes back as Stream_LF |
Encrypted archives, ZIP -d, ZIPINFO | wrong password refused, right password accepted |
UNZIP_VMS /LIST, ZIP_VMS /VMS, a self-extracting executable (UNZIPSFX.EXE joined to a zip) | list shows the file; the executable unpacks all 10 files with the right CRC-32 |
The kit’s own BACKUP saveset (6.2 MB, fixed 32256-byte records) through ZIP -V / UNZIP -V | same format, BACKUP/LIST reads it, CHECKSUM equal; without -V BACKUP says “not a BACKUP save set” |
ZIPDIR.COM / UNZIPALL.COM, example procedures (a tree to a dated archive with every attribute, and back) | all 10 files come back with the right length and CRC-32 |
On the host: a zip made on the VAX unpacks on Linux with unzip -t clean and the SHA-256 of every file equal
to the original’s (10 files, with and without -V); and the 6,225,408-byte saveset, zipped on the VAX with -V
(2,462,042 bytes) and unpacked on Linux, has the same SHA-256 as the saveset itself. (The check script is in the project repository, examples/infozip/tests/.)
Results
(M = measured on the real VAXstation 4000/90 which I named VAX90)
- (M) Clean rebuild from the bundle files, on the real VAXstation 4000/90 (KA49-A, 71 MHz, 128 MB, otherwise idle):
11 min 41 s elapsed, 9 min 58 s CPU: unpacking 25 s, UnZip 6 min 08 s, Zip 4 min 24 s, kit (stage, two help
libraries,
BACKUP/VERIFY) 44 s. Result: 6,225,408-byte saveset, 12,159 blocks. - (M) Installed: 248 files, 10,640 blocks, 37 s for the restore, 42 s for the whole installer including its own smoke test.
- (M) Lifecycle test (install, refuse a second install,
CHECK, keep-changed, uninstall, reinstall,REPLACE): 21 of 21, 3 min 12 s on VAX90 itself: I chose real VAXen for this series, so there was no simulator first. - (M)
RUN_TESTS: 48 of 48 asSYSTEM(4 min 18 s) and 44 of 44 as a fresh, unprivilegedUSER1(1 min 37 s; the saveset test needs a fileUSER1can read and is skipped). - (M) Second machine, VAX60 (VAXstation 4000/60, the slower one): kit B installed in 68 s, lifecycle test 21 of 21 (13 min 24 s
with
RUN_TESTS),RUN_TESTS48 of 48 asSYSTEM(7 min 48 s) and 44 of 44 as a freshUSER1(2 min 40 s). VAX90 was then switched to the same kit B with the installer’sREPLACE(64 s, 248 files out, 248 in) and passed again: 44 of 44 asUSER1(1 min 37 s), 48 of 48 asSYSTEM. - (M) Cross-checks on the host (
host_check.py): a zip made on the VAX (with and without-V) passes the host’sunzip -tand every file has the SHA-256 of the original; the kit’s 6.2 MB saveset zipped on the VAX with-Vand unpacked on Linux has the same SHA-256 as the saveset. - (M)
-aconversion: a 319 KB text of 3000 lines of every length comes back with 3000 records, with and without a final line end; the later “last line lost” fix in Steven Schweda’s newervms.cwas therefore not needed. - (M) Sizes:
UNZIP.EXE264 blocks,UNZIP_CLI.EXE287,UNZIPSFX.EXE132,ZIP.EXE310,ZIP_CLI.EXE351,ZIPCLOAK.EXE115,ZIPNOTE.EXE107,ZIPSPLIT.EXE103. - (E) None of the timing figures is a benchmark: the VAX was idle but its batch queue ran a single job at a time. The
speed of
ZIPon a 71 MHz VAX was not measured separately.
Issues encountered
- An 8-level directory limit: the kit’s own staging tree,
SRC.UNZIP60.VMSunder a home-directory project, is nine levels deep as a full name, and RMS refuses it; the procedures go through a concealed-root logical name. - A command line typed over Telnet is cut at about 250 characters (“terminator not seen”).
- A test that “passed” for the wrong reason: the verification routine accepted a missing listing as “all files found”;
a
DEFINE/USER_MODE SYS$OUTPUTleft pending hid a failure message. Both are fixed and described in the rebuild notes in the project repository (INFOZIP_VAX_REBUILD.md, section 6). DIFFERENCEScannot compare binary Stream_LF files,SEARCH/STATISTICSprints on the terminal and not onSYS$OUTPUT: neither can be captured the way one would expect.
