summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/api/errors.md6
-rw-r--r--lib/internal/errors.js3
-rw-r--r--lib/tty.js13
-rw-r--r--test/pseudo-tty/test-tty-write-stream-resume-crash.js17
-rw-r--r--test/pseudo-tty/test-tty-write-stream-resume-crash.out0
5 files changed, 38 insertions, 1 deletions
diff --git a/doc/api/errors.md b/doc/api/errors.md
index e4a709d45a..72e61c49bb 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -1694,6 +1694,12 @@ A `Transform` stream finished with data still in the write buffer.
The initialization of a TTY failed due to a system error.
+<a id="ERR_TTY_WRITABLE_NOT_READABLE"></a>
+### ERR_TTY_WRITABLE_NOT_READABLE
+
+This `Error` is thrown when a read is attempted on a TTY `WriteStream`,
+such as `process.stdout.on('data')`.
+
<a id="ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET"></a>
### ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 89b51a4cec..0520fbbc6f 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -828,6 +828,9 @@ E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
E('ERR_TRANSFORM_WITH_LENGTH_0',
'Calling transform done when writableState.length != 0', Error);
E('ERR_TTY_INIT_FAILED', 'TTY initialization failed', SystemError);
+E('ERR_TTY_WRITABLE_NOT_READABLE',
+ 'The Writable side of a TTY is not Readable',
+ Error);
E('ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET',
'`process.setupUncaughtExceptionCapture()` was called while a capture ' +
'callback was already active',
diff --git a/lib/tty.js b/lib/tty.js
index b36adf2534..5e0e528c7e 100644
--- a/lib/tty.js
+++ b/lib/tty.js
@@ -25,7 +25,11 @@ const { inherits, _extend } = require('util');
const net = require('net');
const { TTY, isTTY } = process.binding('tty_wrap');
const errors = require('internal/errors');
-const { ERR_INVALID_FD, ERR_TTY_INIT_FAILED } = errors.codes;
+const {
+ ERR_INVALID_FD,
+ ERR_TTY_INIT_FAILED,
+ ERR_TTY_WRITABLE_NOT_READABLE
+} = errors.codes;
const { getColorDepth } = require('internal/tty');
// Lazy loaded for startup performance.
@@ -122,6 +126,13 @@ WriteStream.prototype._refreshSize = function() {
}
};
+// A WriteStream is not readable from, so _read become a no-op.
+// this method could still be called because net.Socket()
+// is a duplex
+WriteStream.prototype._read = function() {
+ this.destroy(new ERR_TTY_WRITABLE_NOT_READABLE());
+};
+
// Backwards-compat
WriteStream.prototype.cursorTo = function(x, y) {
if (readline === undefined) readline = require('readline');
diff --git a/test/pseudo-tty/test-tty-write-stream-resume-crash.js b/test/pseudo-tty/test-tty-write-stream-resume-crash.js
new file mode 100644
index 0000000000..12ec1df45a
--- /dev/null
+++ b/test/pseudo-tty/test-tty-write-stream-resume-crash.js
@@ -0,0 +1,17 @@
+'use strict';
+
+const common = require('../common');
+const { WriteStream } = require('tty');
+const fd = common.getTTYfd();
+
+// Calling resume on a tty.WriteStream should be a no-op
+// Ref: https://github.com/nodejs/node/issues/21203
+
+const stream = new WriteStream(fd);
+stream.resume();
+
+stream.on('error', common.expectsError({
+ code: 'ERR_TTY_WRITABLE_NOT_READABLE',
+ type: Error,
+ message: 'The Writable side of a TTY is not Readable'
+}));
diff --git a/test/pseudo-tty/test-tty-write-stream-resume-crash.out b/test/pseudo-tty/test-tty-write-stream-resume-crash.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/pseudo-tty/test-tty-write-stream-resume-crash.out