Skip to content

Commit 10d0dbc

Browse files
committed
stream_wrap: do not crash if handle was closed
Ignore cases where the handle is already gone, like we do in `handle_wrap.cc`. It should be safe to close handle and then call some binding methods on it, since the internal handle may be shared between `_tls_wrap.js` and `net.js` modules. Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> PR-URL: node-forward/node#37
1 parent b782ef8 commit 10d0dbc

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

src/handle_wrap.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ using v8::Value;
4343
void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
4444
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
4545

46-
if (wrap != nullptr && wrap->handle__ != nullptr) {
46+
if (IsAlive(wrap)) {
4747
uv_ref(wrap->handle__);
4848
wrap->flags_ &= ~kUnref;
4949
}
@@ -53,7 +53,7 @@ void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
5353
void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
5454
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
5555

56-
if (wrap != nullptr && wrap->handle__ != nullptr) {
56+
if (IsAlive(wrap)) {
5757
uv_unref(wrap->handle__);
5858
wrap->flags_ |= kUnref;
5959
}
@@ -66,7 +66,7 @@ void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
6666
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
6767

6868
// guard against uninitialized handle or double close
69-
if (wrap == nullptr || wrap->handle__ == nullptr)
69+
if (!IsAlive(wrap))
7070
return;
7171

7272
CHECK_EQ(false, wrap->persistent().IsEmpty());

src/handle_wrap.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ class HandleWrap : public AsyncWrap {
5757
static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args);
5858
static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args);
5959

60-
inline uv_handle_t* GetHandle() { return handle__; }
60+
static inline bool IsAlive(const HandleWrap* wrap) {
61+
return wrap != nullptr && wrap->GetHandle() != nullptr;
62+
}
63+
64+
inline uv_handle_t* GetHandle() const { return handle__; }
6165

6266
protected:
6367
HandleWrap(Environment* env,

src/stream_wrap.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,18 @@ void StreamWrap::UpdateWriteQueueSize() {
9090

9191
void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
9292
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
93+
if (!IsAlive(wrap))
94+
return args.GetReturnValue().Set(UV_EINVAL);
95+
9396
int err = uv_read_start(wrap->stream(), OnAlloc, OnRead);
9497
args.GetReturnValue().Set(err);
9598
}
9699

97100

98101
void StreamWrap::ReadStop(const FunctionCallbackInfo<Value>& args) {
99102
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
103+
if (!IsAlive(wrap))
104+
return args.GetReturnValue().Set(UV_EINVAL);
100105
int err = uv_read_stop(wrap->stream());
101106
args.GetReturnValue().Set(err);
102107
}
@@ -183,6 +188,8 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
183188
Environment* env = Environment::GetCurrent(args);
184189

185190
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
191+
if (!IsAlive(wrap))
192+
return args.GetReturnValue().Set(UV_EINVAL);
186193

187194
CHECK(args[0]->IsObject());
188195
CHECK(Buffer::HasInstance(args[1]));
@@ -240,6 +247,8 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
240247
int err;
241248

242249
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
250+
if (!IsAlive(wrap))
251+
return args.GetReturnValue().Set(UV_EINVAL);
243252

244253
CHECK(args[0]->IsObject());
245254
CHECK(args[1]->IsString());
@@ -367,6 +376,8 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
367376
Environment* env = Environment::GetCurrent(args);
368377

369378
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
379+
if (!IsAlive(wrap))
380+
return args.GetReturnValue().Set(UV_EINVAL);
370381

371382
CHECK(args[0]->IsObject());
372383
CHECK(args[1]->IsArray());
@@ -493,6 +504,8 @@ void StreamWrap::WriteBinaryString(const FunctionCallbackInfo<Value>& args) {
493504

494505
void StreamWrap::SetBlocking(const FunctionCallbackInfo<Value>& args) {
495506
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
507+
if (!IsAlive(wrap))
508+
return args.GetReturnValue().Set(UV_EINVAL);
496509
CHECK_GT(args.Length(), 0);
497510
int err = uv_stream_set_blocking(wrap->stream(), args[0]->IsTrue());
498511
args.GetReturnValue().Set(err);
@@ -537,6 +550,8 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
537550
Environment* env = Environment::GetCurrent(args);
538551

539552
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
553+
if (!IsAlive(wrap))
554+
return args.GetReturnValue().Set(UV_EINVAL);
540555

541556
CHECK(args[0]->IsObject());
542557
Local<Object> req_wrap_obj = args[0].As<Object>();

0 commit comments

Comments
 (0)