From ceeefda0247ec2066a96581dd61ecf15a1d2b626 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Tue, 24 Mar 2026 09:31:47 +0100 Subject: [PATCH] fix: Gzip comment with header checksum produces corrupt streams The Gzip operation manually set the FCOMMENT flag bit after zlibjs had already calculated the header CRC16, corrupting the checksum. Fix by setting options.flags.fcomment before calling compress(), letting zlibjs handle the flag internally. Closes #2243 --- src/core/operations/Gzip.mjs | 4 +-- tests/operations/tests/Gzip.mjs | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/core/operations/Gzip.mjs b/src/core/operations/Gzip.mjs index 093ae6a4..43eaf091 100644 --- a/src/core/operations/Gzip.mjs +++ b/src/core/operations/Gzip.mjs @@ -74,13 +74,11 @@ class Gzip extends Operation { } if (comment.length) { options.flags.comment = true; + options.flags.fcomment = true; options.comment = comment; } const gzipObj = new Zlib.Gzip(new Uint8Array(input), options); const compressed = new Uint8Array(gzipObj.compress()); - if (options.flags.comment && !(compressed[3] & 0x10)) { - compressed[3] |= 0x10; - } return compressed.buffer; } diff --git a/tests/operations/tests/Gzip.mjs b/tests/operations/tests/Gzip.mjs index c9b2b8ca..a936f5d0 100644 --- a/tests/operations/tests/Gzip.mjs +++ b/tests/operations/tests/Gzip.mjs @@ -86,4 +86,64 @@ TestRegister.addTests([ } ] }, + { + name: "Gzip: Comment with checksum round-trips through Gunzip", + input: "hello hello hello", + expectedOutput: "hello hello hello", + recipeConfig: [ + { + op: "Gzip", + args: ["Dynamic Huffman Coding", "", "test", true] + }, + { + op: "Gunzip", + args: [] + } + ] + }, + { + name: "Gzip: Filename and comment with checksum round-trips through Gunzip", + input: "The quick brown fox jumped over the slow dog", + expectedOutput: "The quick brown fox jumped over the slow dog", + recipeConfig: [ + { + op: "Gzip", + args: ["Dynamic Huffman Coding", "file.txt", "a comment", true] + }, + { + op: "Gunzip", + args: [] + } + ] + }, + { + name: "Gzip: No comment, with checksum round-trips through Gunzip", + input: "The quick brown fox jumped over the slow dog", + expectedOutput: "The quick brown fox jumped over the slow dog", + recipeConfig: [ + { + op: "Gzip", + args: ["Dynamic Huffman Coding", "", "", true] + }, + { + op: "Gunzip", + args: [] + } + ] + }, + { + name: "Gzip: No options round-trips through Gunzip", + input: "The quick brown fox jumped over the slow dog", + expectedOutput: "The quick brown fox jumped over the slow dog", + recipeConfig: [ + { + op: "Gzip", + args: ["Dynamic Huffman Coding", "", "", false] + }, + { + op: "Gunzip", + args: [] + } + ] + }, ]);