Description
corrupt-when-streamed.zip
The streaming Zip + ZipDeflate API produces invalid compressed data for certain small binary files. This is not batch-dependent — it reproduces with a single 691-byte file.
Reproduction
const fs = require('fs');
const { Zip, ZipDeflate, unzipSync } = require('fflate');
// 691-byte binary file (attached)
const fileData = fs.readFileSync('corrupt-when-streamed.eot');
const chunks = [];
const z = new Zip();
z.ondata = (err, data, final) => {
if (err) throw err;
chunks.push(data);
if (final) {
const combined = Buffer.concat(chunks);
unzipSync(new Uint8Array(combined)); // throws "invalid distance"
}
};
const zf = new ZipDeflate('font.eot', { level: 6 });
z.add(zf);
zf.push(fileData, true);
z.end();
Findings
| Compression level |
Streaming (ZipDeflate) |
Synchronous (zipSync) |
| 0 (store) |
PASS |
PASS |
| 1 |
PASS |
PASS |
| 2 |
FAIL — invalid distance |
PASS |
| 3 |
FAIL — invalid distance |
PASS |
| 4 |
FAIL — invalid distance |
PASS |
| 5 |
FAIL — invalid distance |
PASS |
| 6 |
FAIL — invalid distance |
PASS |
| 7 |
FAIL — invalid distance |
PASS |
| 8 |
FAIL — invalid distance |
PASS |
| 9 |
FAIL — invalid distance |
PASS |
- Reproduces with a single 691-byte binary file — no large batch needed
- Affects compression levels 2–9. Levels 0 (store) and 1 pass
- Only the streaming
Zip/ZipDeflate path is broken; zipSync works at all levels
- The deflate stream itself is invalid (decompression fails with "invalid distance too far back")
- ZIP structure (local file headers, CRC32, data descriptors, central directory) is correct
- Tested on fflate 0.8.2
Attached
corrupt-when-streamed.eot — 691-byte binary file that triggers the bug.
Workaround
Switch from streaming Zip/ZipDeflate to zipSync.
Description
corrupt-when-streamed.zip
The streaming
Zip+ZipDeflateAPI produces invalid compressed data for certain small binary files. This is not batch-dependent — it reproduces with a single 691-byte file.Reproduction
Findings
ZipDeflate)zipSync)Zip/ZipDeflatepath is broken;zipSyncworks at all levelsAttached
corrupt-when-streamed.eot— 691-byte binary file that triggers the bug.Workaround
Switch from streaming
Zip/ZipDeflatetozipSync.