Skip to content

Instantly share code, notes, and snippets.

@spalt08
Created September 25, 2025 21:16
Show Gist options
  • Select an option

  • Save spalt08/98554a15a3cdf13ca5695c03b35bcd3f to your computer and use it in GitHub Desktop.

Select an option

Save spalt08/98554a15a3cdf13ca5695c03b35bcd3f to your computer and use it in GitHub Desktop.
Reproduction of inconsistent DecompressionStream behaviour
// Console-friendly version of the script
// Just paste it into the dev-tools console in Chrome/Safari/Firefox
(async function test() {
const plainText = "test-payload";
const plainTextBytes = new TextEncoder().encode(plainText);
// Compress
const compressionStream = new CompressionStream("deflate");
const compressionWriter = compressionStream.writable.getWriter();
compressionWriter.write(plainTextBytes);
compressionWriter.close();
const originalCompressedBytes = await readStream(compressionStream.readable);
// Add arbitrary padding to the compressed bytes
const paddedCompressedBytes = padBuffer(originalCompressedBytes, 1);
// Decompress
const decompressionStream = new DecompressionStream("deflate");
const decompressionWriter = decompressionStream.writable.getWriter();
decompressionWriter.write(paddedCompressedBytes);
decompressionWriter.close();
// In Chrome decompressedBytes are still available and fine, whereas in Safari and Firefox - not available.
// Also, the output depends on input chunking which is not guaranteed.
const decompressedBytes = await readStream(decompressionStream.readable);
const decompressedText = new TextDecoder().decode(decompressedBytes);
console.log("Decompressed text:", decompressedText);
return decompressedText;
})();
async function readStream(readableStream) {
const chunks = [];
await readableStream
.pipeTo(
new WritableStream({
write(chunk) {
chunks.push(chunk);
},
abort(reason) {
console.log("abort", reason);
},
})
)
.catch((error) => {
console.log("error", error);
});
return new Blob(chunks)
.arrayBuffer()
.then((buffer) => new Uint8Array(buffer));
}
function padBuffer(buffer, paddingLength) {
const paddedBuffer = new Uint8Array(buffer.length + paddingLength);
paddedBuffer.set(buffer, 0);
for (let i = 0; i < paddingLength; i++) {
paddedBuffer[buffer.length + i] = Math.random() * 0xff;
}
return paddedBuffer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment