Skip to content

Commit 28db96f

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 a0778a9 commit 28db96f

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
@@ -546,6 +546,16 @@ function processCallback() {
546546
return;
547547
}
548548

549+
if (availInAfter > 0) {
550+
// If we have more input that should be written, but we also have output
551+
// space available, that means that the compression library was not
552+
// interested in receiving more data, and in particular that the input
553+
// stream has ended early.
554+
// This applies to streams where we don't check data past the end of
555+
// what was consumed; that is, everything except Gunzip/Unzip.
556+
self.push(null);
557+
}
558+
549559
// finished with the chunk.
550560
this.buffer = null;
551561
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)