Commit 776285835ca for nodejs
commit 776285835ca204111533bbe2367035fe61839b06
Author: Matteo Collina <hello@matteocollina.com>
Date: Tue Nov 3 11:16:22 2026 +0100
zlib: handle params callback after destroy
When params() queues its flush behind another write, destroying the
stream invokes the flush callback after the native handle is closed.
Propagate the write error instead of accessing the closed handle.
Assisted-by: Codex
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs-private/node-private/pull/1037
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
CVE-ID: CVE-2026-123862
diff --git a/lib/zlib.js b/lib/zlib.js
index f1d93665967..a2d2c158e5d 100644
--- a/lib/zlib.js
+++ b/lib/zlib.js
@@ -789,14 +789,16 @@ const zlibDefaultOpts = {
// before adjusting the parameters. In particular, the call to the native
// `params()` function should not happen while a write is currently in progress
// on the threadpool.
-function paramsAfterFlushCallback(level, strategy, callback) {
- assert(this._handle, 'zlib binding closed');
- this._handle.params(level, strategy);
- if (!this.destroyed) {
- this._level = level;
- this._strategy = strategy;
- if (callback) callback();
+function paramsAfterFlushCallback(level, strategy, callback, err) {
+ if (err || this.destroyed || !this._handle) {
+ if (callback) callback(err);
+ return;
}
+
+ this._handle.params(level, strategy);
+ this._level = level;
+ this._strategy = strategy;
+ if (callback) callback();
}
// Base class for all streams actually backed by zlib and using zlib-specific
diff --git a/test/parallel/test-zlib-params.js b/test/parallel/test-zlib-params.js
index 18271fe022a..9c110287b26 100644
--- a/test/parallel/test-zlib-params.js
+++ b/test/parallel/test-zlib-params.js
@@ -1,5 +1,5 @@
'use strict';
-require('../common');
+const common = require('../common');
const assert = require('assert');
const zlib = require('zlib');
const fixtures = require('../common/fixtures');
@@ -38,3 +38,13 @@ process.once('exit', function() {
const actual = Buffer.concat(bufs);
assert.deepStrictEqual(actual, expected);
});
+
+{
+ const deflater = zlib.createDeflate();
+ deflater.write('x');
+ deflater.params(9, zlib.constants.Z_DEFAULT_STRATEGY,
+ common.mustCall((err) => {
+ assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED');
+ }));
+ deflater.destroy();
+}