Skip to content

Commit 0b3936b

Browse files
addaleaxFishrock123
authored andcommitted
zlib: Fix handling of gzip magic bytes mid-file
Only treat the gzip magic bytes, when encountered within the file after reading a single block, as the start of a new member when the previous member has ended. Add test files that reliably reproduce #5852. The gzipped file in test/fixtures/pseudo-multimember-gzip.gz contains the gzip magic bytes exactly at the position that node encounters after having read a single block, leading it to believe that a new data member is starting. Fixes: #5852 PR-URL: #5863 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 7d73e60 commit 0b3936b

4 files changed

+24
-1
lines changed

src/node_zlib.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ class ZCtx : public AsyncWrap {
258258
}
259259
}
260260
while (ctx->strm_.avail_in >= GZIP_MIN_HEADER_SIZE &&
261-
ctx->mode_ == GUNZIP) {
261+
ctx->mode_ == GUNZIP &&
262+
ctx->err_ == Z_STREAM_END) {
262263
// Bytes remain in input buffer. Perhaps this is another compressed
263264
// member in the same archive, or just trailing garbage.
264265
// Check the header to find out.
161 Bytes
Binary file not shown.
148 Bytes
Binary file not shown.

test/parallel/test-zlib-from-concatenated-gzip.js

+22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
const common = require('../common');
55
const assert = require('assert');
66
const zlib = require('zlib');
7+
const path = require('path');
8+
const fs = require('fs');
79

810
const data = Buffer.concat([
911
zlib.gzipSync('abc'),
@@ -16,3 +18,23 @@ zlib.gunzip(data, common.mustCall((err, result) => {
1618
assert.ifError(err);
1719
assert.equal(result, 'abcdef', 'result should match original string');
1820
}));
21+
22+
// files that have the "right" magic bytes for starting a new gzip member
23+
// in the middle of themselves, even if they are part of a single
24+
// regularly compressed member
25+
const pmmFileZlib = path.join(common.fixturesDir, 'pseudo-multimember-gzip.z');
26+
const pmmFileGz = path.join(common.fixturesDir, 'pseudo-multimember-gzip.gz');
27+
28+
const pmmExpected = zlib.inflateSync(fs.readFileSync(pmmFileZlib));
29+
const pmmResultBuffers = [];
30+
31+
fs.createReadStream(pmmFileGz)
32+
.pipe(zlib.createGunzip())
33+
.on('error', (err) => {
34+
assert.ifError(err);
35+
})
36+
.on('data', (data) => pmmResultBuffers.push(data))
37+
.on('finish', common.mustCall(() => {
38+
assert.deepStrictEqual(Buffer.concat(pmmResultBuffers), pmmExpected,
39+
'result should match original random garbage');
40+
}));

0 commit comments

Comments
 (0)