Skip to content

Commit 21db422

Browse files
committed
fixup! zlib: do not coalesce multiple .flush() calls
1 parent 5e592d2 commit 21db422

2 files changed

Lines changed: 39 additions & 10 deletions

File tree

lib/zlib.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,28 @@ ZlibBase.prototype._flush = function(callback) {
316316
// Z_SYNC_FLUSH < Z_FULL_FLUSH < Z_FINISH
317317
const flushiness = [];
318318
let i = 0;
319-
for (const flushFlag of [Z_NO_FLUSH, Z_BLOCK, Z_PARTIAL_FLUSH,
320-
Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH]) {
319+
const kFlushFlagList = [Z_NO_FLUSH, Z_BLOCK, Z_PARTIAL_FLUSH,
320+
Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH];
321+
for (const flushFlag of kFlushFlagList) {
321322
flushiness[flushFlag] = i++;
322323
}
323324

324325
function maxFlush(a, b) {
325326
return flushiness[a] > flushiness[b] ? a : b;
326327
}
327328

329+
// Set up a list of 'special' buffers that can be written using .write()
330+
// from the .flush() code as a way of introducing flushing operations into the
331+
// write sequence.
332+
const kFlushBuffers = [];
333+
{
334+
const dummyArrayBuffer = new ArrayBuffer();
335+
for (const flushFlag of kFlushFlagList) {
336+
kFlushBuffers[flushFlag] = Buffer.from(dummyArrayBuffer);
337+
kFlushBuffers[flushFlag][kFlushFlag] = flushFlag;
338+
}
339+
}
340+
328341
ZlibBase.prototype.flush = function(kind, callback) {
329342
const ws = this._writableState;
330343

@@ -340,9 +353,7 @@ ZlibBase.prototype.flush = function(kind, callback) {
340353
if (callback)
341354
this.once('end', callback);
342355
} else {
343-
const flushBuffer = Buffer.alloc(0);
344-
flushBuffer[kFlushFlag] = kind;
345-
this.write(flushBuffer, '', callback);
356+
this.write(kFlushBuffers[kind], '', callback);
346357
}
347358
};
348359

test/parallel/test-zlib-flush-write-sync-interleaved.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,31 @@ const decompress = createGunzip();
1313
decompress.setEncoding('utf8');
1414

1515
const events = [];
16+
const compressedChunks = [];
1617

1718
for (const chunk of ['abc', 'def', 'ghi']) {
1819
compress.write(chunk, common.mustCall(() => events.push({ written: chunk })));
1920
compress.flush(Z_PARTIAL_FLUSH, common.mustCall(() => {
2021
events.push('flushed');
21-
decompress.write(compress.read(), common.mustCall(() => {
22-
events.push({ read: decompress.read() });
23-
}));
22+
const chunk = compress.read();
23+
if (chunk !== null)
24+
compressedChunks.push(chunk);
25+
}));
26+
}
27+
28+
compress.end(common.mustCall(() => {
29+
events.push('compress end');
30+
writeToDecompress();
31+
}));
32+
33+
function writeToDecompress() {
34+
// Write the compressed chunks to a decompressor, one by one, in order to
35+
// verify that the flushes actually worked.
36+
const chunk = compressedChunks.shift();
37+
if (chunk === undefined) return decompress.end();
38+
decompress.write(chunk, common.mustCall(() => {
39+
events.push({ read: decompress.read() });
40+
writeToDecompress();
2441
}));
2542
}
2643

@@ -29,11 +46,12 @@ process.on('exit', () => {
2946
{ written: 'abc' },
3047
'flushed',
3148
{ written: 'def' },
32-
{ read: 'abc' },
3349
'flushed',
3450
{ written: 'ghi' },
35-
{ read: 'def' },
3651
'flushed',
52+
'compress end',
53+
{ read: 'abc' },
54+
{ read: 'def' },
3755
{ read: 'ghi' }
3856
]);
3957
});

0 commit comments

Comments
 (0)