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: https://github.com/nodejs/node/issues/5852 PR-URL: https://github.com/nodejs/node/pull/5863 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit is contained in:
parent
7d73e60f60
commit
0b3936b49f
@ -258,7 +258,8 @@ class ZCtx : public AsyncWrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (ctx->strm_.avail_in >= GZIP_MIN_HEADER_SIZE &&
|
while (ctx->strm_.avail_in >= GZIP_MIN_HEADER_SIZE &&
|
||||||
ctx->mode_ == GUNZIP) {
|
ctx->mode_ == GUNZIP &&
|
||||||
|
ctx->err_ == Z_STREAM_END) {
|
||||||
// Bytes remain in input buffer. Perhaps this is another compressed
|
// Bytes remain in input buffer. Perhaps this is another compressed
|
||||||
// member in the same archive, or just trailing garbage.
|
// member in the same archive, or just trailing garbage.
|
||||||
// Check the header to find out.
|
// Check the header to find out.
|
||||||
|
BIN
test/fixtures/pseudo-multimember-gzip.gz
vendored
Normal file
BIN
test/fixtures/pseudo-multimember-gzip.gz
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/pseudo-multimember-gzip.z
vendored
Normal file
BIN
test/fixtures/pseudo-multimember-gzip.z
vendored
Normal file
Binary file not shown.
@ -4,6 +4,8 @@
|
|||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const zlib = require('zlib');
|
const zlib = require('zlib');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
const data = Buffer.concat([
|
const data = Buffer.concat([
|
||||||
zlib.gzipSync('abc'),
|
zlib.gzipSync('abc'),
|
||||||
@ -16,3 +18,23 @@ zlib.gunzip(data, common.mustCall((err, result) => {
|
|||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
assert.equal(result, 'abcdef', 'result should match original string');
|
assert.equal(result, 'abcdef', 'result should match original string');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// files that have the "right" magic bytes for starting a new gzip member
|
||||||
|
// in the middle of themselves, even if they are part of a single
|
||||||
|
// regularly compressed member
|
||||||
|
const pmmFileZlib = path.join(common.fixturesDir, 'pseudo-multimember-gzip.z');
|
||||||
|
const pmmFileGz = path.join(common.fixturesDir, 'pseudo-multimember-gzip.gz');
|
||||||
|
|
||||||
|
const pmmExpected = zlib.inflateSync(fs.readFileSync(pmmFileZlib));
|
||||||
|
const pmmResultBuffers = [];
|
||||||
|
|
||||||
|
fs.createReadStream(pmmFileGz)
|
||||||
|
.pipe(zlib.createGunzip())
|
||||||
|
.on('error', (err) => {
|
||||||
|
assert.ifError(err);
|
||||||
|
})
|
||||||
|
.on('data', (data) => pmmResultBuffers.push(data))
|
||||||
|
.on('finish', common.mustCall(() => {
|
||||||
|
assert.deepStrictEqual(Buffer.concat(pmmResultBuffers), pmmExpected,
|
||||||
|
'result should match original random garbage');
|
||||||
|
}));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user