// The island's node:zlib shim, differentially against Node: round trips // in all three formats (zlib/raw/gzip) plus auto-detecting unzip, sync // and callback spellings, the buffering stream classes through a pipe, // corrupt-input error text (zlib's own message, Node's too), and fixed // compressed blobs inflating byte-exactly. Raw DEFLATE OUTPUT bytes are // zlib-build-dependent, so round trips — never output bytes — are the // contract (the scr_zlib.c corpus rule). import zlib, { constants, createGunzip, createGzip, gunzipSync, gzipSync } from "node:zlib"; export async function report() { const lines = []; const push = (label, v) => lines.push(label + " " + v); const sample = "the quick brown fox jumps over the lazy dog ☃".repeat(20); push("roundtrip-zlib:", zlib.inflateSync(zlib.deflateSync(sample)).toString("utf8") === sample); push("roundtrip-raw:", zlib.inflateRawSync(zlib.deflateRawSync(sample)).toString("utf8") === sample); push("roundtrip-gzip:", gunzipSync(gzipSync(sample)).toString("utf8") === sample); push("unzip-auto:", zlib.unzipSync(gzipSync("a")).toString() + zlib.unzipSync(zlib.deflateSync("b")).toString()); push("gzip-magic:", gzipSync("x")[0].toString(16) + gzipSync("x")[1].toString(16)); push("level:", zlib.inflateSync(zlib.deflateSync(sample, { level: 9 })).toString("utf8") === sample); // a fixed zlib blob ("hello") inflates identically everywhere push("fixed-blob:", zlib.inflateSync(Buffer.from("789ccb48cdc9c90700062c0215", "hex")).toString("utf8")); const errOf = (fn) => { try { fn(); return "no-throw"; } catch (e) { return (e.code || e.constructor.name) + ":" + e.message; } }; push("corrupt:", errOf(() => zlib.inflateSync(Buffer.from([1, 2, 3, 4])))); push("truncated:", errOf(() => zlib.inflateSync(zlib.deflateSync(sample).subarray(0, 8)))); const cb = await new Promise((res) => zlib.gzip(sample, (err, out) => { res(err + "|" + (gunzipSync(out).toString("utf8") === sample)); })); push("callback:", cb); // stream classes through a pipe (the island's are buffering transforms: // output arrives at end — both lanes see identical final bytes) const chunks = []; const gz = createGzip(); const gun = createGunzip(); gz.pipe(gun); gun.on("data", (c) => chunks.push(c)); gz.write(sample.slice(0, 100)); gz.write(sample.slice(100)); gz.end(); await new Promise((res) => gun.on("end", res)); push("stream:", Buffer.concat(chunks).toString("utf8") === sample); push("constants:", [constants.Z_SYNC_FLUSH, constants.Z_FINISH, constants.Z_DEFAULT_COMPRESSION, constants.Z_BEST_COMPRESSION, constants.Z_DEFAULT_WINDOWBITS].join(",")); push("classes:", [typeof zlib.Inflate, typeof zlib.createInflateRaw, typeof zlib.createBrotliDecompress].join(",")); return lines.join("\n"); }