From a09e2fd43b5cccbb07a3c94951cc01087ff6eb7c Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Wed, 25 Oct 2017 09:26:20 -0400 Subject: [PATCH] net: fix timeout with null handle This commit handles the case where _onTimeout is called with a null handle. Backport-PR-URL: https://github.com/nodejs/node/pull/16420 Refs: https://github.com/nodejs/node/pull/15791 Fixes: https://github.com/nodejs/node/issues/16484 PR-URL: https://github.com/nodejs/node/pull/16489 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Refael Ackermann --- lib/net.js | 16 +++++++++------- test/parallel/test-net-timeout-no-handle.js | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 test/parallel/test-net-timeout-no-handle.js diff --git a/lib/net.js b/lib/net.js index 21e25854a52fc9..78337cda6dd808 100644 --- a/lib/net.js +++ b/lib/net.js @@ -334,13 +334,15 @@ Socket.prototype.setTimeout = function(msecs, callback) { Socket.prototype._onTimeout = function() { - // `.prevWriteQueueSize` !== `.updateWriteQueueSize()` means there is - // an active write in progress, so we suppress the timeout. - const prevWriteQueueSize = this._handle.writeQueueSize; - if (prevWriteQueueSize > 0 && - prevWriteQueueSize !== this._handle.updateWriteQueueSize()) { - this._unrefTimer(); - return; + if (this._handle) { + // `.prevWriteQueueSize` !== `.updateWriteQueueSize()` means there is + // an active write in progress, so we suppress the timeout. + const prevWriteQueueSize = this._handle.writeQueueSize; + if (prevWriteQueueSize > 0 && + prevWriteQueueSize !== this._handle.updateWriteQueueSize()) { + this._unrefTimer(); + return; + } } debug('_onTimeout'); this.emit('timeout'); diff --git a/test/parallel/test-net-timeout-no-handle.js b/test/parallel/test-net-timeout-no-handle.js new file mode 100644 index 00000000000000..539f661cae8414 --- /dev/null +++ b/test/parallel/test-net-timeout-no-handle.js @@ -0,0 +1,17 @@ +'use strict'; + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const socket = new net.Socket(); +socket.setTimeout(common.platformTimeout(50)); + +socket.on('timeout', common.mustCall(() => { + assert.strictEqual(socket._handle, null); +})); + +socket.on('connect', common.mustNotCall()); + +// since the timeout is unrefed, the code will exit without this +setTimeout(() => {}, common.platformTimeout(200));