Skip to content

Commit 851a691

Browse files
addaleaxBridgeAR
authored andcommitted
zlib: report premature ends earlier
Report end-of-stream when decompressing when we detect it, and do not wait until the writable side of a zlib stream is closed as well. Refs: #26332 PR-URL: #26363 Refs: #26332 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 4c254d6 commit 851a691

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/zlib.js

+10
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,16 @@ function processCallback() {
545545
return;
546546
}
547547

548+
if (availInAfter > 0) {
549+
// If we have more input that should be written, but we also have output
550+
// space available, that means that the compression library was not
551+
// interested in receiving more data, and in particular that the input
552+
// stream has ended early.
553+
// This applies to streams where we don't check data past the end of
554+
// what was consumed; that is, everything except Gunzip/Unzip.
555+
self.push(null);
556+
}
557+
548558
// finished with the chunk.
549559
this.buffer = null;
550560
this.cb();
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
const common = require('../common');
3+
const zlib = require('zlib');
4+
const assert = require('assert');
5+
6+
const input = '0123456789'.repeat(4);
7+
8+
for (const [ compress, decompressor ] of [
9+
[ zlib.deflateRawSync, zlib.createInflateRaw ],
10+
[ zlib.deflateSync, zlib.createInflate ],
11+
[ zlib.brotliCompressSync, zlib.createBrotliDecompress ]
12+
]) {
13+
const compressed = compress(input);
14+
const trailingData = Buffer.from('not valid compressed data');
15+
16+
for (const variant of [
17+
(stream) => { stream.end(compressed); },
18+
(stream) => { stream.write(compressed); stream.write(trailingData); },
19+
(stream) => { stream.write(compressed); stream.end(trailingData); },
20+
(stream) => { stream.write(Buffer.concat([compressed, trailingData])); },
21+
(stream) => { stream.end(Buffer.concat([compressed, trailingData])); }
22+
]) {
23+
let output = '';
24+
const stream = decompressor();
25+
stream.setEncoding('utf8');
26+
stream.on('data', (chunk) => output += chunk);
27+
stream.on('end', common.mustCall(() => {
28+
assert.strictEqual(output, input);
29+
assert.strictEqual(stream.bytesWritten, compressed.length);
30+
}));
31+
variant(stream);
32+
}
33+
}

0 commit comments

Comments
 (0)