Skip to content

Commit

Permalink
src: make StreamPipe::Unpipe() more resilient
Browse files Browse the repository at this point in the history
Clean up `StreamPipe::Unpipe()` to be more resilient against
unexpected exceptions, in particular while executing its
`MakeCallback()` line (which can fail in the presence of
termination exceptions), and clean up the getter/setter part
of the code to match that pattern as well (even though it should
not fail as part of regular operations).

PR-URL: #25716
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>
  • Loading branch information
addaleax committed Feb 1, 2019
1 parent 0b014d5 commit b779c07
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions src/stream_pipe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using v8::Context;
using v8::External;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Local;
Expand Down Expand Up @@ -77,30 +78,35 @@ void StreamPipe::Unpipe() {
Context::Scope context_scope(env->context());
Local<Object> object = pipe->object();

if (object->Has(env->context(), env->onunpipe_string()).FromJust()) {
pipe->MakeCallback(env->onunpipe_string(), 0, nullptr).ToLocalChecked();
Local<Value> onunpipe;
if (!object->Get(env->context(), env->onunpipe_string()).ToLocal(&onunpipe))
return;
if (onunpipe->IsFunction() &&
pipe->MakeCallback(onunpipe.As<Function>(), 0, nullptr).IsEmpty()) {
return;
}

// Set all the links established in the constructor to `null`.
Local<Value> null = Null(env->isolate());

Local<Value> source_v;
Local<Value> sink_v;
source_v = object->Get(env->context(), env->source_string())
.ToLocalChecked();
sink_v = object->Get(env->context(), env->sink_string())
.ToLocalChecked();
CHECK(source_v->IsObject());
CHECK(sink_v->IsObject());

object->Set(env->context(), env->source_string(), null).FromJust();
object->Set(env->context(), env->sink_string(), null).FromJust();
source_v.As<Object>()->Set(env->context(),
env->pipe_target_string(),
null).FromJust();
sink_v.As<Object>()->Set(env->context(),
env->pipe_source_string(),
null).FromJust();
if (!object->Get(env->context(), env->source_string()).ToLocal(&source_v) ||
!object->Get(env->context(), env->sink_string()).ToLocal(&sink_v) ||
!source_v->IsObject() || !sink_v->IsObject()) {
return;
}

if (object->Set(env->context(), env->source_string(), null).IsNothing() ||
object->Set(env->context(), env->sink_string(), null).IsNothing() ||
source_v.As<Object>()
->Set(env->context(), env->pipe_target_string(), null)
.IsNothing() ||
sink_v.As<Object>()
->Set(env->context(), env->pipe_source_string(), null)
.IsNothing()) {
return;
}
}, static_cast<void*>(this), object());
}

Expand Down

0 comments on commit b779c07

Please sign in to comment.