Browse Source

tty_wrap: throw when uv_tty_init() returns error

Also add checks in lib/tty.js and tests.

PR-URL: https://github.com/nodejs/node/pull/12892
Ref: https://github.com/nodejs/node/pull/11883
Ref: https://github.com/nodejs/node/pull/8531
Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
v6
Trevor Norris 8 years ago
committed by Anna Henningsen
parent
commit
4b9d84df51
No known key found for this signature in database GPG Key ID: D8B9F5AEAE84E4CF
  1. 8
      lib/tty.js
  2. 14
      src/tty_wrap.cc
  3. 3
      src/tty_wrap.h
  4. 36
      test/parallel/test-ttywrap-invalid-fd.js

8
lib/tty.js

@ -37,6 +37,8 @@ exports.isatty = function(fd) {
function ReadStream(fd, options) { function ReadStream(fd, options) {
if (!(this instanceof ReadStream)) if (!(this instanceof ReadStream))
return new ReadStream(fd, options); return new ReadStream(fd, options);
if (fd >> 0 !== fd || fd < 0)
throw new RangeError('fd must be positive integer: ' + fd);
options = util._extend({ options = util._extend({
highWaterMark: 0, highWaterMark: 0,
@ -62,7 +64,11 @@ ReadStream.prototype.setRawMode = function(flag) {
function WriteStream(fd) { function WriteStream(fd) {
if (!(this instanceof WriteStream)) return new WriteStream(fd); if (!(this instanceof WriteStream))
return new WriteStream(fd);
if (fd >> 0 !== fd || fd < 0)
throw new RangeError('fd must be positive integer: ' + fd);
net.Socket.call(this, { net.Socket.call(this, {
handle: new TTY(fd, false), handle: new TTY(fd, false),
readable: false, readable: false,

14
src/tty_wrap.cc

@ -150,17 +150,25 @@ void TTYWrap::New(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
CHECK_GE(fd, 0); CHECK_GE(fd, 0);
TTYWrap* wrap = new TTYWrap(env, args.This(), fd, args[1]->IsTrue()); int err = 0;
TTYWrap* wrap = new TTYWrap(env, args.This(), fd, args[1]->IsTrue(), &err);
if (err != 0)
return env->ThrowUVException(err, "uv_tty_init");
wrap->UpdateWriteQueueSize(); wrap->UpdateWriteQueueSize();
} }
TTYWrap::TTYWrap(Environment* env, Local<Object> object, int fd, bool readable) TTYWrap::TTYWrap(Environment* env,
Local<Object> object,
int fd,
bool readable,
int* init_err)
: StreamWrap(env, : StreamWrap(env,
object, object,
reinterpret_cast<uv_stream_t*>(&handle_), reinterpret_cast<uv_stream_t*>(&handle_),
AsyncWrap::PROVIDER_TTYWRAP) { AsyncWrap::PROVIDER_TTYWRAP) {
uv_tty_init(env->event_loop(), &handle_, fd, readable); *init_err = uv_tty_init(env->event_loop(), &handle_, fd, readable);
} }
} // namespace node } // namespace node

3
src/tty_wrap.h

@ -44,7 +44,8 @@ class TTYWrap : public StreamWrap {
TTYWrap(Environment* env, TTYWrap(Environment* env,
v8::Local<v8::Object> object, v8::Local<v8::Object> object,
int fd, int fd,
bool readable); bool readable,
int* init_err);
static void GuessHandleType(const v8::FunctionCallbackInfo<v8::Value>& args); static void GuessHandleType(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsTTY(const v8::FunctionCallbackInfo<v8::Value>& args); static void IsTTY(const v8::FunctionCallbackInfo<v8::Value>& args);

36
test/parallel/test-ttywrap-invalid-fd.js

@ -0,0 +1,36 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
const tty = require('tty');
assert.throws(() => {
new tty.WriteStream(-1);
}, /fd must be positive integer:/);
const err_regex = common.isWindows ?
/^Error: EBADF: bad file descriptor, uv_tty_init$/ :
/^Error: EINVAL: invalid argument, uv_tty_init$/;
assert.throws(() => {
let fd = 2;
// Get first known bad file descriptor.
try {
while (fs.fstatSync(++fd));
} catch (e) { }
new tty.WriteStream(fd);
}, err_regex);
assert.throws(() => {
new tty.ReadStream(-1);
}, /fd must be positive integer:/);
assert.throws(() => {
let fd = 2;
// Get first known bad file descriptor.
try {
while (fs.fstatSync(++fd));
} catch (e) { }
new tty.ReadStream(fd);
}, err_regex);
Loading…
Cancel
Save