summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base-object-inl.h4
-rw-r--r--src/fs_event_wrap.cc6
-rw-r--r--src/handle_wrap.cc12
-rw-r--r--src/js_stream.cc23
-rw-r--r--src/node_contextify.cc23
-rw-r--r--src/node_crypto.cc276
-rw-r--r--src/node_http_parser.cc24
-rw-r--r--src/node_internals.h2
-rw-r--r--src/node_stat_watcher.cc6
-rw-r--r--src/node_wrap.h2
-rw-r--r--src/node_zlib.cc15
-rw-r--r--src/pipe_wrap.cc18
-rw-r--r--src/process_wrap.cc7
-rw-r--r--src/signal_wrap.cc6
-rw-r--r--src/stream_base-inl.h16
-rw-r--r--src/stream_base.cc3
-rw-r--r--src/stream_wrap.cc6
-rw-r--r--src/tcp_wrap.cc46
-rw-r--r--src/tls_wrap.cc28
-rw-r--r--src/tty_wrap.cc10
-rw-r--r--src/udp_wrap.cc29
-rw-r--r--src/util.h20
-rw-r--r--test/parallel/test-stream-base-no-abort.js58
23 files changed, 462 insertions, 178 deletions
diff --git a/src/base-object-inl.h b/src/base-object-inl.h
index 87159ffc68..86add5e3b3 100644
--- a/src/base-object-inl.h
+++ b/src/base-object-inl.h
@@ -14,6 +14,10 @@ inline BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> handle)
: handle_(env->isolate(), handle),
env_(env) {
CHECK_EQ(false, handle.IsEmpty());
+ // The zero field holds a pointer to the handle. Immediately set it to
+ // nullptr in case it's accessed by the user before construction is complete.
+ if (handle->InternalFieldCount() > 0)
+ handle->SetAlignedPointerInInternalField(0, nullptr);
}
diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc
index 48b6f4eca8..3f0df1140c 100644
--- a/src/fs_event_wrap.cc
+++ b/src/fs_event_wrap.cc
@@ -86,7 +86,8 @@ void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {
void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- FSEventWrap* wrap = Unwrap<FSEventWrap>(args.Holder());
+ FSEventWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
static const char kErrMsg[] = "filename must be a string or Buffer";
if (args.Length() < 1)
@@ -181,7 +182,8 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) {
- FSEventWrap* wrap = Unwrap<FSEventWrap>(args.Holder());
+ FSEventWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (wrap == nullptr || wrap->initialized_ == false)
return;
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc
index c5792338af..daf821e1d2 100644
--- a/src/handle_wrap.cc
+++ b/src/handle_wrap.cc
@@ -18,7 +18,8 @@ using v8::Value;
void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
- HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
+ HandleWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (IsAlive(wrap))
uv_ref(wrap->GetHandle());
@@ -26,7 +27,8 @@ void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
- HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
+ HandleWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (IsAlive(wrap))
uv_unref(wrap->GetHandle());
@@ -34,7 +36,8 @@ void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
void HandleWrap::HasRef(const FunctionCallbackInfo<Value>& args) {
- HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
+ HandleWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
args.GetReturnValue().Set(HasRef(wrap));
}
@@ -42,7 +45,8 @@ void HandleWrap::HasRef(const FunctionCallbackInfo<Value>& args) {
void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());
+ HandleWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
// Guard against uninitialized handle or double close.
if (!IsAlive(wrap))
diff --git a/src/js_stream.cc b/src/js_stream.cc
index 6ebdb5a356..e51c4ae9b3 100644
--- a/src/js_stream.cc
+++ b/src/js_stream.cc
@@ -135,7 +135,8 @@ static void FreeCallback(char* data, void* hint) {
void JSStream::DoAlloc(const FunctionCallbackInfo<Value>& args) {
- JSStream* wrap = Unwrap<JSStream>(args.Holder());
+ JSStream* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
uv_buf_t buf;
wrap->OnAlloc(args[0]->Int32Value(), &buf);
@@ -150,7 +151,8 @@ void JSStream::DoAlloc(const FunctionCallbackInfo<Value>& args) {
void JSStream::DoRead(const FunctionCallbackInfo<Value>& args) {
- JSStream* wrap = Unwrap<JSStream>(args.Holder());
+ JSStream* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK(Buffer::HasInstance(args[1]));
uv_buf_t buf = uv_buf_init(Buffer::Data(args[1]), Buffer::Length(args[1]));
@@ -159,8 +161,11 @@ void JSStream::DoRead(const FunctionCallbackInfo<Value>& args) {
void JSStream::DoAfterWrite(const FunctionCallbackInfo<Value>& args) {
- JSStream* wrap = Unwrap<JSStream>(args.Holder());
- WriteWrap* w = Unwrap<WriteWrap>(args[0].As<Object>());
+ JSStream* wrap;
+ CHECK(args[0]->IsObject());
+ WriteWrap* w;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
+ ASSIGN_OR_RETURN_UNWRAP(&w, args[0].As<Object>());
wrap->OnAfterWrite(w);
}
@@ -168,14 +173,17 @@ void JSStream::DoAfterWrite(const FunctionCallbackInfo<Value>& args) {
template <class Wrap>
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) {
- Wrap* w = Unwrap<Wrap>(args[0].As<Object>());
+ Wrap* w;
+ CHECK(args[0]->IsObject());
+ ASSIGN_OR_RETURN_UNWRAP(&w, args[0].As<Object>());
w->Done(args[1]->Int32Value());
}
void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
- JSStream* wrap = Unwrap<JSStream>(args.Holder());
+ JSStream* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK(Buffer::HasInstance(args[0]));
char* data = Buffer::Data(args[0]);
@@ -197,7 +205,8 @@ void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
void JSStream::EmitEOF(const FunctionCallbackInfo<Value>& args) {
- JSStream* wrap = Unwrap<JSStream>(args.Holder());
+ JSStream* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
wrap->OnRead(UV_EOF, nullptr);
}
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index bef7168ada..774871b852 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -343,8 +343,8 @@ class ContextifyContext {
static void GlobalPropertyGetterCallback(
Local<Name> property,
const PropertyCallbackInfo<Value>& args) {
- ContextifyContext* ctx =
- Unwrap<ContextifyContext>(args.Data().As<Object>());
+ ContextifyContext* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Data().As<Object>());
// Stil initializing
if (ctx->context_.IsEmpty())
@@ -373,8 +373,8 @@ class ContextifyContext {
Local<Name> property,
Local<Value> value,
const PropertyCallbackInfo<Value>& args) {
- ContextifyContext* ctx =
- Unwrap<ContextifyContext>(args.Data().As<Object>());
+ ContextifyContext* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Data().As<Object>());
// Stil initializing
if (ctx->context_.IsEmpty())
@@ -387,8 +387,8 @@ class ContextifyContext {
static void GlobalPropertyQueryCallback(
Local<Name> property,
const PropertyCallbackInfo<Integer>& args) {
- ContextifyContext* ctx =
- Unwrap<ContextifyContext>(args.Data().As<Object>());
+ ContextifyContext* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Data().As<Object>());
// Stil initializing
if (ctx->context_.IsEmpty())
@@ -414,8 +414,8 @@ class ContextifyContext {
static void GlobalPropertyDeleterCallback(
Local<Name> property,
const PropertyCallbackInfo<Boolean>& args) {
- ContextifyContext* ctx =
- Unwrap<ContextifyContext>(args.Data().As<Object>());
+ ContextifyContext* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Data().As<Object>());
// Stil initializing
if (ctx->context_.IsEmpty())
@@ -430,8 +430,8 @@ class ContextifyContext {
static void GlobalPropertyEnumeratorCallback(
const PropertyCallbackInfo<Array>& args) {
- ContextifyContext* ctx =
- Unwrap<ContextifyContext>(args.Data().As<Object>());
+ ContextifyContext* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Data().As<Object>());
// Stil initializing
if (ctx->context_.IsEmpty())
@@ -806,7 +806,8 @@ class ContextifyScript : public BaseObject {
return false;
}
- ContextifyScript* wrapped_script = Unwrap<ContextifyScript>(args.Holder());
+ ContextifyScript* wrapped_script;
+ ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder(), false);
Local<UnboundScript> unbound_script =
PersistentToLocal(env->isolate(), wrapped_script->script_);
Local<Script> script = unbound_script->BindToCurrentContext();
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 71e1272e9d..873fbfb410 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -338,7 +338,8 @@ void SecureContext::New(const FunctionCallbackInfo<Value>& args) {
void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
Environment* env = sc->env();
const SSL_METHOD* method = SSLv23_method();
@@ -434,7 +435,8 @@ static BIO* LoadBIO(Environment* env, Local<Value> v) {
void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
unsigned int len = args.Length();
if (len < 1) {
@@ -639,7 +641,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
if (args.Length() != 1) {
return env->ThrowTypeError("Certificate argument is mandatory");
@@ -680,7 +683,8 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
bool newCAStore = false;
Environment* env = Environment::GetCurrent(args);
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.
@@ -714,7 +718,8 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
if (args.Length() != 1) {
return env->ThrowTypeError("CRL argument is mandatory");
@@ -745,7 +750,8 @@ void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.
@@ -779,7 +785,8 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
Environment* env = sc->env();
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.
@@ -796,7 +803,8 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
Environment* env = sc->env();
if (args.Length() != 1)
@@ -824,7 +832,8 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.This());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
Environment* env = sc->env();
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.
@@ -863,7 +872,8 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
if (args.Length() != 1 || !args[0]->IntegerValue()) {
return sc->env()->ThrowTypeError("Options must be an integer value");
@@ -875,7 +885,8 @@ void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetSessionIdContext(
const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
Environment* env = sc->env();
if (args.Length() != 1) {
@@ -913,7 +924,8 @@ void SecureContext::SetSessionIdContext(
void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
if (args.Length() != 1 || !args[0]->IsInt32()) {
return sc->env()->ThrowTypeError(
@@ -926,7 +938,8 @@ void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
sc->FreeCTXMem();
}
@@ -943,7 +956,8 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
char* pass = nullptr;
bool ret = false;
- SecureContext* sc = Unwrap<SecureContext>(args.Holder());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder());
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.
@@ -1018,7 +1032,8 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
- SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
+ SecureContext* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Local<Object> buff = Buffer::New(wrap->env(), 48).ToLocalChecked();
if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
@@ -1034,7 +1049,8 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
#if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
- SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
+ SecureContext* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Environment* env = wrap->env();
if (args.Length() < 1) {
@@ -1059,7 +1075,8 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
- SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
+ SecureContext* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
wrap->ctx_->freelist_max_len = args[0]->Int32Value();
}
@@ -1067,7 +1084,8 @@ void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
void SecureContext::EnableTicketKeyCallback(
const FunctionCallbackInfo<Value>& args) {
- SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
+ SecureContext* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_, TicketKeyCallback);
}
@@ -1156,15 +1174,17 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
void SecureContext::CtxGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
- SSL_CTX* ctx = Unwrap<SecureContext>(info.This())->ctx_;
- Local<External> ext = External::New(info.GetIsolate(), ctx);
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
+ Local<External> ext = External::New(info.GetIsolate(), sc->ctx_);
info.GetReturnValue().Set(ext);
}
template <bool primary>
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
- SecureContext* wrap = Unwrap<SecureContext>(args.Holder());
+ SecureContext* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Environment* env = wrap->env();
X509* cert;
@@ -1543,7 +1563,8 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
template <class Base>
void SSLWrap<Base>::GetPeerCertificate(
const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->ssl_env();
ClearErrorOnReturn clear_error_on_return;
@@ -1651,7 +1672,8 @@ template <class Base>
void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
SSL_SESSION* sess = SSL_get_session(w->ssl_);
if (sess == nullptr)
@@ -1672,7 +1694,8 @@ template <class Base>
void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
if (args.Length() < 1) {
return env->ThrowError("Session argument is mandatory");
@@ -1701,7 +1724,8 @@ void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->ssl_env();
if (args.Length() >= 1 && Buffer::HasInstance(args[0])) {
@@ -1732,7 +1756,8 @@ void SSLWrap<Base>::LoadSession(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
bool yes = SSL_session_reused(w->ssl_);
args.GetReturnValue().Set(yes);
}
@@ -1740,14 +1765,16 @@ void SSLWrap<Base>::IsSessionReused(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::EndParser(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
w->hello_parser_.End();
}
template <class Base>
void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence unused variable warning.
@@ -1759,7 +1786,8 @@ void SSLWrap<Base>::Renegotiate(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
int rv = SSL_shutdown(w->ssl_);
args.GetReturnValue().Set(rv);
@@ -1768,7 +1796,8 @@ void SSLWrap<Base>::Shutdown(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->ssl_env();
SSL_SESSION* sess = SSL_get_session(w->ssl_);
@@ -1786,7 +1815,8 @@ void SSLWrap<Base>::GetTLSTicket(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
w->new_session_wait_ = false;
w->NewSessionDoneCb();
}
@@ -1798,7 +1828,8 @@ void SSLWrap<Base>::SetOCSPResponse(
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
HandleScope scope(args.GetIsolate());
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->env();
if (args.Length() < 1)
@@ -1817,7 +1848,8 @@ void SSLWrap<Base>::RequestOCSP(
#ifdef NODE__HAVE_TLSEXT_STATUS_CB
HandleScope scope(args.GetIsolate());
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
SSL_set_tlsext_status_type(w->ssl_, TLSEXT_STATUSTYPE_ocsp);
#endif // NODE__HAVE_TLSEXT_STATUS_CB
@@ -1827,7 +1859,8 @@ void SSLWrap<Base>::RequestOCSP(
template <class Base>
void SSLWrap<Base>::GetEphemeralKeyInfo(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = Environment::GetCurrent(args);
CHECK_NE(w->ssl_, nullptr);
@@ -1875,7 +1908,8 @@ void SSLWrap<Base>::SetMaxSendFragment(
HandleScope scope(args.GetIsolate());
CHECK(args.Length() >= 1 && args[0]->IsNumber());
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
int rv = SSL_set_max_send_fragment(w->ssl_, args[0]->Int32Value());
args.GetReturnValue().Set(rv);
@@ -1885,7 +1919,8 @@ void SSLWrap<Base>::SetMaxSendFragment(
template <class Base>
void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
bool yes = SSL_is_init_finished(w->ssl_);
args.GetReturnValue().Set(yes);
}
@@ -1893,7 +1928,8 @@ void SSLWrap<Base>::IsInitFinished(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
// XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no
// peer certificate is questionable but it's compatible with what was
@@ -1956,7 +1992,8 @@ void SSLWrap<Base>::VerifyError(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->ssl_env();
const SSL_CIPHER* c = SSL_get_current_cipher(w->ssl_);
@@ -1975,7 +2012,8 @@ void SSLWrap<Base>::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
const char* tls_version = SSL_get_version(w->ssl_);
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), tls_version));
@@ -2079,7 +2117,8 @@ int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
template <class Base>
void SSLWrap<Base>::GetNegotiatedProto(
const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->env();
if (w->is_client()) {
@@ -2106,7 +2145,8 @@ void SSLWrap<Base>::GetNegotiatedProto(
template <class Base>
void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->env();
if (args.Length() < 1)
@@ -2173,7 +2213,8 @@ void SSLWrap<Base>::GetALPNNegotiatedProto(
const FunctionCallbackInfo<v8::Value>& args) {
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
HandleScope scope(args.GetIsolate());
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
const unsigned char* alpn_proto;
unsigned int alpn_proto_len;
@@ -2194,7 +2235,8 @@ void SSLWrap<Base>::SetALPNProtocols(
const FunctionCallbackInfo<v8::Value>& args) {
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
HandleScope scope(args.GetIsolate());
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->env();
if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
return env->ThrowTypeError("Must give a Buffer as first argument");
@@ -2328,7 +2370,8 @@ int SSLWrap<Base>::SSLCertCallback(SSL* s, void* arg) {
template <class Base>
void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
- Base* w = Unwrap<Base>(args.Holder());
+ Base* w;
+ ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder());
Environment* env = w->env();
CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_);
@@ -2342,7 +2385,8 @@ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
goto fire_cb;
if (cons->HasInstance(ctx)) {
- SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, ctx.As<Object>());
w->sni_context_.Reset();
w->sni_context_.Reset(env->isolate(), ctx);
@@ -2393,7 +2437,9 @@ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::SSLGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
- SSL* ssl = Unwrap<Base>(info.This())->ssl_;
+ Base* base;
+ ASSIGN_OR_RETURN_UNWRAP(&base, info.This());
+ SSL* ssl = base->ssl_;
Local<External> ext = External::New(info.GetIsolate(), ssl);
info.GetReturnValue().Set(ext);
}
@@ -2746,7 +2792,8 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
env->secure_context_constructor_template();
if (secure_context_constructor_template->HasInstance(ret)) {
conn->sni_context_.Reset(env->isolate(), ret);
- SecureContext* sc = Unwrap<SecureContext>(ret.As<Object>());
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, ret.As<Object>(), SSL_TLSEXT_ERR_NOACK);
conn->SetSNIContext(sc);
} else {
return SSL_TLSEXT_ERR_NOACK;
@@ -2766,7 +2813,8 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
return;
}
- SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject(env->isolate()));
+ SecureContext* sc;
+ ASSIGN_OR_RETURN_UNWRAP(&sc, args[0].As<Object>());
bool is_server = args[1]->BooleanValue();
@@ -2854,7 +2902,8 @@ void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) {
void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
Environment* env = conn->env();
if (args.Length() < 3) {
@@ -2902,7 +2951,8 @@ void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
Environment* env = conn->env();
if (args.Length() < 3) {
@@ -2955,21 +3005,24 @@ void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
int bytes_pending = BIO_pending(conn->bio_read_);
args.GetReturnValue().Set(bytes_pending);
}
void Connection::EncPending(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
int bytes_pending = BIO_pending(conn->bio_write_);
args.GetReturnValue().Set(bytes_pending);
}
void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
Environment* env = conn->env();
if (args.Length() < 3) {
@@ -2998,7 +3051,8 @@ void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
Environment* env = conn->env();
if (args.Length() < 3) {
@@ -3051,7 +3105,8 @@ void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
void Connection::Start(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
int rv = 0;
if (!SSL_is_init_finished(conn->ssl_)) {
@@ -3074,7 +3129,8 @@ void Connection::Start(const FunctionCallbackInfo<Value>& args) {
void Connection::Close(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
if (conn->ssl_ != nullptr) {
SSL_free(conn->ssl_);
@@ -3085,7 +3141,8 @@ void Connection::Close(const FunctionCallbackInfo<Value>& args) {
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
if (conn->is_server() && !conn->servername_.IsEmpty()) {
args.GetReturnValue().Set(conn->servername_);
@@ -3096,7 +3153,8 @@ void Connection::GetServername(const FunctionCallbackInfo<Value>& args) {
void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
- Connection* conn = Unwrap<Connection>(args.Holder());
+ Connection* conn;
+ ASSIGN_OR_RETURN_UNWRAP(&conn, args.Holder());
Environment* env = conn->env();
if (args.Length() < 1 || !args[0]->IsFunction()) {
@@ -3186,7 +3244,8 @@ void CipherBase::Init(const char* cipher_type,
void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
Environment* env = cipher->env();
if (args.Length() < 2) {
@@ -3240,7 +3299,8 @@ void CipherBase::InitIv(const char* cipher_type,
void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
Environment* env = cipher->env();
if (args.Length() < 3) {
@@ -3283,7 +3343,8 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
char* out = nullptr;
unsigned int out_len = 0;
@@ -3316,7 +3377,8 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
if (!buf->IsObject() || !Buffer::HasInstance(buf))
return env->ThrowTypeError("Auth tag must be a Buffer");
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
env->ThrowError("Attempting to set auth tag in unsupported state");
@@ -3343,7 +3405,8 @@ void CipherBase::SetAAD(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "AAD");
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
if (!cipher->SetAAD(Buffer::Data(args[0]), Buffer::Length(args[0])))
env->ThrowError("Attempting to set AAD in unsupported state");
@@ -3380,7 +3443,8 @@ bool CipherBase::Update(const char* data,
void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Cipher data");
@@ -3425,7 +3489,8 @@ bool CipherBase::SetAutoPadding(bool auto_padding) {
void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) {
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue());
}
@@ -3461,7 +3526,8 @@ bool CipherBase::Final(unsigned char** out, int *out_len) {
void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- CipherBase* cipher = Unwrap<CipherBase>(args.Holder());
+ CipherBase* cipher;
+ ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
unsigned char* out_value = nullptr;
int out_len = -1;
@@ -3535,7 +3601,8 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
- Hmac* hmac = Unwrap<Hmac>(args.Holder());
+ Hmac* hmac;
+ ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
Environment* env = hmac->env();
if (args.Length() < 2) {
@@ -3563,7 +3630,8 @@ bool Hmac::HmacUpdate(const char* data, int len) {
void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Hmac* hmac = Unwrap<Hmac>(args.Holder());
+ Hmac* hmac;
+ ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data");
@@ -3600,7 +3668,8 @@ bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Hmac* hmac = Unwrap<Hmac>(args.Holder());
+ Hmac* hmac;
+ ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
enum encoding encoding = BUFFER;
if (args.Length() >= 1) {
@@ -3682,7 +3751,8 @@ bool Hash::HashUpdate(const char* data, int len) {
void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Hash* hash = Unwrap<Hash>(args.Holder());
+ Hash* hash;
+ ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data");
@@ -3715,7 +3785,8 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Hash* hash = Unwrap<Hash>(args.Holder());
+ Hash* hash;
+ ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
if (!hash->initialised_) {
return env->ThrowError("Not initialized");
@@ -3821,7 +3892,8 @@ SignBase::Error Sign::SignInit(const char* sign_type) {
void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
- Sign* sign = Unwrap<Sign>(args.Holder());
+ Sign* sign;
+ ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
Environment* env = sign->env();
if (args.Length() == 0) {
@@ -3847,7 +3919,8 @@ SignBase::Error Sign::SignUpdate(const char* data, int len) {
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Sign* sign = Unwrap<Sign>(args.Holder());
+ Sign* sign;
+ ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data");
@@ -3941,7 +4014,8 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Sign* sign = Unwrap<Sign>(args.Holder());
+ Sign* sign;
+ ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
unsigned char* md_value;
unsigned int md_len;
@@ -4024,7 +4098,8 @@ SignBase::Error Verify::VerifyInit(const char* verify_type) {
void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
- Verify* verify = Unwrap<Verify>(args.Holder());
+ Verify* verify;
+ ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
Environment* env = verify->env();
if (args.Length() == 0) {
@@ -4052,7 +4127,8 @@ SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Verify* verify = Unwrap<Verify>(args.Holder());
+ Verify* verify;
+ ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
THROW_AND_RETURN_IF_NOT_STRING_OR_BUFFER(args[0], "Data");
@@ -4151,7 +4227,8 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Verify* verify = Unwrap<Verify>(args.Holder());
+ Verify* verify;
+ ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Key");
char* kbuf = Buffer::Data(args[0]);
@@ -4493,7 +4570,8 @@ void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4516,7 +4594,8 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4534,7 +4613,8 @@ void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4552,7 +4632,8 @@ void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4575,7 +4656,8 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4598,7 +4680,8 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_) {
return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
@@ -4667,7 +4750,8 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
Environment* env = diffieHellman->env();
if (!diffieHellman->initialised_) {
@@ -4686,7 +4770,8 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
Environment* env = diffieHellman->env();
if (!diffieHellman->initialised_) {
@@ -4709,7 +4794,8 @@ void DiffieHellman::VerifyErrorGetter(Local<String> property,
const PropertyCallbackInfo<Value>& args) {
HandleScope scope(args.GetIsolate());
- DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
+ DiffieHellman* diffieHellman;
+ ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder());
if (!diffieHellman->initialised_)
return ThrowCryptoError(diffieHellman->env(), ERR_get_error(),
@@ -4771,7 +4857,8 @@ void ECDH::New(const FunctionCallbackInfo<Value>& args) {
void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
if (!EC_KEY_generate_key(ecdh->key_))
return env->ThrowError("Failed to generate EC_KEY");
@@ -4812,7 +4899,8 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Data");
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
if (!ecdh->IsKeyPairValid())
return env->ThrowError("Invalid key pair");
@@ -4846,7 +4934,8 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
// Conversion form
CHECK_EQ(args.Length(), 1);
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_);
if (pub == nullptr)
@@ -4878,7 +4967,8 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_);
if (b == nullptr)
@@ -4902,7 +4992,8 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Private key");
@@ -4955,7 +5046,8 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ECDH* ecdh = Unwrap<ECDH>(args.Holder());
+ ECDH* ecdh;
+ ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder());
THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Public key");
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc
index 4a0dd580a4..fd5e7c8e21 100644
--- a/src/node_http_parser.cc
+++ b/src/node_http_parser.cc
@@ -368,7 +368,8 @@ class Parser : public AsyncWrap {
static void Close(const FunctionCallbackInfo<Value>& args) {
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
if (--parser->refcount_ == 0)
delete parser;
@@ -391,7 +392,8 @@ class Parser : public AsyncWrap {
// var bytesParsed = parser->execute(buffer);
static void Execute(const FunctionCallbackInfo<Value>& args) {
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
CHECK(parser->current_buffer_.IsEmpty());
CHECK_EQ(parser->current_buffer_len_, 0);
CHECK_EQ(parser->current_buffer_data_, nullptr);
@@ -416,7 +418,8 @@ class Parser : public AsyncWrap {
static void Finish(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
CHECK(parser->current_buffer_.IsEmpty());
parser->got_exception_ = false;
@@ -447,7 +450,8 @@ class Parser : public AsyncWrap {
static_cast<http_parser_type>(args[0]->Int32Value());
CHECK(type == HTTP_REQUEST || type == HTTP_RESPONSE);
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
// Should always be called from the same context.
CHECK_EQ(env, parser->env());
parser->Init(type);
@@ -457,7 +461,8 @@ class Parser : public AsyncWrap {
template <bool should_pause>
static void Pause(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
// Should always be called from the same context.
CHECK_EQ(env, parser->env());
http_parser_pause(&parser->parser_, should_pause);
@@ -465,7 +470,8 @@ class Parser : public AsyncWrap {
static void Consume(const FunctionCallbackInfo<Value>& args) {
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
Local<External> stream_obj = args[0].As<External>();
StreamBase* stream = static_cast<StreamBase*>(stream_obj->Value());
CHECK_NE(stream, nullptr);
@@ -481,7 +487,8 @@ class Parser : public AsyncWrap {
static void Unconsume(const FunctionCallbackInfo<Value>& args) {
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
// Already unconsumed
if (parser->prev_alloc_cb_.is_empty())
@@ -503,7 +510,8 @@ class Parser : public AsyncWrap {
static void GetCurrentBuffer(const FunctionCallbackInfo<Value>& args) {
- Parser* parser = Unwrap<Parser>(args.Holder());
+ Parser* parser;
+ ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder());
Local<Object> ret = Buffer::Copy(
parser->env(),
diff --git a/src/node_internals.h b/src/node_internals.h
index 0d660705c8..a46d3130bf 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -85,6 +85,8 @@ v8::Local<v8::Object> AddressToJS(
template <typename T, int (*F)(const typename T::HandleType*, sockaddr*, int*)>
void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>& args) {
T* const wrap = Unwrap<T>(args.Holder());
+ if (wrap == nullptr)
+ return args.GetReturnValue().Set(UV_EBADF);
CHECK(args[0]->IsObject());
sockaddr_storage storage;
int addrlen = sizeof(storage);
diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc
index 4fa01794f6..cff92e3404 100644
--- a/src/node_stat_watcher.cc
+++ b/src/node_stat_watcher.cc
@@ -84,7 +84,8 @@ void StatWatcher::New(const FunctionCallbackInfo<Value>& args) {
void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 3);
- StatWatcher* wrap = Unwrap<StatWatcher>(args.Holder());
+ StatWatcher* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
node::Utf8Value path(args.GetIsolate(), args[0]);
const bool persistent = args[1]->BooleanValue();
const uint32_t interval = args[2]->Uint32Value();
@@ -97,7 +98,8 @@ void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) {
void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) {
- StatWatcher* wrap = Unwrap<StatWatcher>(args.Holder());
+ StatWatcher* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Environment* env = wrap->env();
Context::Scope context_scope(env->context());
wrap->MakeCallback(env->onstop_string(), 0, nullptr);
diff --git a/src/node_wrap.h b/src/node_wrap.h
index d508a4a470..b2d6af8ad5 100644
--- a/src/node_wrap.h
+++ b/src/node_wrap.h
@@ -39,6 +39,8 @@ inline uv_stream_t* HandleToStream(Environment* env,
v8::HandleScope scope(env->isolate());
WITH_GENERIC_UV_STREAM(env, obj, {
+ if (wrap == nullptr)
+ return nullptr;
return reinterpret_cast<uv_stream_t*>(wrap->UVHandle());
}, {});
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index aee1cbae95..4de9d7cdc2 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -109,7 +109,8 @@ class ZCtx : public AsyncWrap {
static void Close(const FunctionCallbackInfo<Value>& args) {
- ZCtx* ctx = Unwrap<ZCtx>(args.Holder());
+ ZCtx* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
ctx->Close();
}
@@ -119,7 +120,8 @@ class ZCtx : public AsyncWrap {
static void Write(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 7);
- ZCtx* ctx = Unwrap<ZCtx>(args.Holder());
+ ZCtx* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
CHECK(ctx->init_done_ && "write before init");
CHECK(ctx->mode_ != NONE && "already finalized");
@@ -431,7 +433,8 @@ class ZCtx : public AsyncWrap {
CHECK((args.Length() == 4 || args.Length() == 5) &&
"init(windowBits, level, memLevel, strategy, [dictionary])");
- ZCtx* ctx = Unwrap<ZCtx>(args.Holder());
+ ZCtx* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
int windowBits = args[0]->Uint32Value();
CHECK((windowBits >= 8 && windowBits <= 15) && "invalid windowBits");
@@ -467,12 +470,14 @@ class ZCtx : public AsyncWrap {
static void Params(const FunctionCallbackInfo<Value>& args) {
CHECK(args.Length() == 2 && "params(level, strategy)");
- ZCtx* ctx = Unwrap<ZCtx>(args.Holder());
+ ZCtx* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
Params(ctx, args[0]->Int32Value(), args[1]->Int32Value());
}
static void Reset(const FunctionCallbackInfo<Value> &args) {
- ZCtx* ctx = Unwrap<ZCtx>(args.Holder());
+ ZCtx* ctx;
+ ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
Reset(ctx);
SetDictionary(ctx);
}
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 7be07de74b..286ea30a87 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -138,7 +138,8 @@ PipeWrap::PipeWrap(Environment* env,
void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
- PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
node::Utf8Value name(args.GetIsolate(), args[0]);
int err = uv_pipe_bind(&wrap->handle_, *name);
args.GetReturnValue().Set(err);
@@ -147,7 +148,8 @@ void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
#ifdef _WIN32
void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
- PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int instances = args[0]->Int32Value();
uv_pipe_pending_instances(&wrap->handle_, instances);
}
@@ -155,7 +157,8 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
- PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int backlog = args[0]->Int32Value();
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
backlog,
@@ -191,7 +194,8 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
Local<Object> client_obj = Instantiate(env, pipe_wrap);
// Unwrap the client javascript object.
- PipeWrap* wrap = Unwrap<PipeWrap>(client_obj);
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, client_obj);
uv_stream_t* client_handle = reinterpret_cast<uv_stream_t*>(&wrap->handle_);
if (uv_accept(handle, client_handle))
return;
@@ -242,7 +246,8 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int fd = args[0]->Int32Value();
@@ -256,7 +261,8 @@ void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- PipeWrap* wrap = Unwrap<PipeWrap>(args.Holder());
+ PipeWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK(args[0]->IsObject());
CHECK(args[1]->IsString());
diff --git a/src/process_wrap.cc b/src/process_wrap.cc
index 36c6cfe3ad..2b214d1d47 100644
--- a/src/process_wrap.cc
+++ b/src/process_wrap.cc
@@ -86,6 +86,7 @@ class ProcessWrap : public HandleWrap {
UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE);
Local<String> handle_key = env->handle_string();
Local<Object> handle = stdio->Get(handle_key).As<Object>();
+ CHECK(!handle.IsEmpty());
options->stdio[i].data.stream =
reinterpret_cast<uv_stream_t*>(
Unwrap<PipeWrap>(handle)->UVHandle());
@@ -109,7 +110,8 @@ class ProcessWrap : public HandleWrap {
static void Spawn(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- ProcessWrap* wrap = Unwrap<ProcessWrap>(args.Holder());
+ ProcessWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Local<Object> js_options = args[0]->ToObject(env->isolate());
@@ -233,7 +235,8 @@ class ProcessWrap : public HandleWrap {
}
static void Kill(const FunctionCallbackInfo<Value>& args) {
- ProcessWrap* wrap = Unwrap<ProcessWrap>(args.Holder());
+ ProcessWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int signal = args[0]->Int32Value();
int err = uv_process_kill(&wrap->process_, signal);
args.GetReturnValue().Set(err);
diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc
index ec052366f2..3ee0251f9b 100644
--- a/src/signal_wrap.cc
+++ b/src/signal_wrap.cc
@@ -62,14 +62,16 @@ class SignalWrap : public HandleWrap {
}
static void Start(const FunctionCallbackInfo<Value>& args) {
- SignalWrap* wrap = Unwrap<SignalWrap>(args.Holder());
+ SignalWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int signum = args[0]->Int32Value();
int err = uv_signal_start(&wrap->handle_, OnSignal, signum);
args.GetReturnValue().Set(err);
}
static void Stop(const FunctionCallbackInfo<Value>& args) {
- SignalWrap* wrap = Unwrap<SignalWrap>(args.Holder());
+ SignalWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
int err = uv_signal_stop(&wrap->handle_);
args.GetReturnValue().Set(err);
}
diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h
index e8e73f007e..bdc8211707 100644
--- a/src/stream_base-inl.h
+++ b/src/stream_base-inl.h
@@ -80,8 +80,9 @@ void StreamBase::GetFD(Local<String> key,
Base* handle = Unwrap<Base>(args.Holder());
// Mimic implementation of StreamBase::GetFD() and UDPWrap::GetFD().
- if (handle == nullptr)
- return args.GetReturnValue().Set(-1);
+ ASSIGN_OR_RETURN_UNWRAP(&handle,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EINVAL));
StreamBase* wrap = static_cast<StreamBase*>(handle);
if (!wrap->IsAlive())
@@ -97,8 +98,9 @@ void StreamBase::GetBytesRead(Local<String> key,
Base* handle = Unwrap<Base>(args.Holder());
// The handle instance hasn't been set. So no bytes could have been read.
- if (handle == nullptr)
- return args.GetReturnValue().Set(0);
+ ASSIGN_OR_RETURN_UNWRAP(&handle,
+ args.Holder(),
+ args.GetReturnValue().Set(0));
StreamBase* wrap = static_cast<StreamBase*>(handle);
// uint64_t -> double. 53bits is enough for all real cases.
@@ -111,8 +113,7 @@ void StreamBase::GetExternal(Local<String> key,
const PropertyCallbackInfo<Value>& args) {
Base* handle = Unwrap<Base>(args.Holder());
- if (handle == nullptr)
- return args.GetReturnValue().SetUndefined();
+ ASSIGN_OR_RETURN_UNWRAP(&handle, args.Holder());
StreamBase* wrap = static_cast<StreamBase*>(handle);
Local<External> ext = External::New(args.GetIsolate(), wrap);
@@ -125,8 +126,7 @@ template <class Base,
void StreamBase::JSMethod(const FunctionCallbackInfo<Value>& args) {
Base* handle = Unwrap<Base>(args.Holder());
- if (handle == nullptr)
- return args.GetReturnValue().SetUndefined();
+ ASSIGN_OR_RETURN_UNWRAP(&handle, args.Holder());
StreamBase* wrap = static_cast<StreamBase*>(handle);
if (!wrap->IsAlive())
diff --git a/src/stream_base.cc b/src/stream_base.cc
index 7561a09998..8db127dff6 100644
--- a/src/stream_base.cc
+++ b/src/stream_base.cc
@@ -329,7 +329,8 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
uv_handle_t* send_handle = nullptr;
if (!send_handle_obj.IsEmpty()) {
- HandleWrap* wrap = Unwrap<HandleWrap>(send_handle_obj);
+ HandleWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, send_handle_obj, UV_EINVAL);
send_handle = wrap->GetHandle();
// Reference StreamWrap instance to prevent it from being garbage
// collected before `AfterWrite` is called.
diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc
index b942e48078..f3f1d3bfdf 100644
--- a/src/stream_wrap.cc
+++ b/src/stream_wrap.cc
@@ -170,7 +170,8 @@ static Local<Object> AcceptHandle(Environment* env, StreamWrap* parent) {
if (wrap_obj.IsEmpty())
return Local<Object>();
- WrapType* wrap = Unwrap<WrapType>(wrap_obj);
+ WrapType* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, wrap_obj, Local<Object>());
handle = wrap->UVHandle();
if (uv_accept(parent->stream(), reinterpret_cast<uv_stream_t*>(handle)))
@@ -262,7 +263,8 @@ void StreamWrap::OnRead(uv_stream_t* handle,
void StreamWrap::SetBlocking(const FunctionCallbackInfo<Value>& args) {
- StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
+ StreamWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK_GT(args.Length(), 0);
if (!wrap->IsAlive())
diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc
index 9e95bac0e2..6904b27efd 100644
--- a/src/tcp_wrap.cc
+++ b/src/tcp_wrap.cc
@@ -164,7 +164,10 @@ TCPWrap::~TCPWrap() {
void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int enable = static_cast<int>(args[0]->BooleanValue());
int err = uv_tcp_nodelay(&wrap->handle_, enable);
args.GetReturnValue().Set(err);
@@ -172,7 +175,10 @@ void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {
void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int enable = args[0]->Int32Value();
unsigned int delay = args[1]->Uint32Value();
int err = uv_tcp_keepalive(&wrap->handle_, enable, delay);
@@ -182,7 +188,10 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {
#ifdef _WIN32
void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
bool enable = args[0]->BooleanValue();
int err = uv_tcp_simultaneous_accepts(&wrap->handle_, enable);
args.GetReturnValue().Set(err);
@@ -191,14 +200,20 @@ void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {
void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int fd = static_cast<int>(args[0]->IntegerValue());
uv_tcp_open(&wrap->handle_, fd);
}
void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
node::Utf8Value ip_address(args.GetIsolate(), args[0]);
int port = args[1]->Int32Value();
sockaddr_in addr;
@@ -213,7 +228,10 @@ void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
node::Utf8Value ip6_address(args.GetIsolate(), args[0]);
int port = args[1]->Int32Value();
sockaddr_in6 addr;
@@ -228,7 +246,10 @@ void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) {
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int backlog = args[0]->Int32Value();
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
backlog,
@@ -261,6 +282,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
// Unwrap the client javascript object.
TCPWrap* wrap = Unwrap<TCPWrap>(client_obj);
+ CHECK_NE(wrap, nullptr);
uv_stream_t* client_handle = reinterpret_cast<uv_stream_t*>(&wrap->handle_);
if (uv_accept(handle, client_handle))
return;
@@ -304,7 +326,10 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) {
void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
CHECK(args[0]->IsObject());
CHECK(args[1]->IsString());
@@ -335,7 +360,10 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TCPWrap* wrap = Unwrap<TCPWrap>(args.Holder());
+ TCPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
CHECK(args[0]->IsObject());
CHECK(args[1]->IsString());
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 779587fe36..20bbce50de 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -54,6 +54,9 @@ TLSWrap::TLSWrap(Environment* env,
node::Wrap(object(), this);
MakeWeak(this);
+ // sc comes from an Unwrap. Make sure it was assigned.
+ CHECK_NE(sc, nullptr);
+
// We've our own session callbacks
SSL_CTX_sess_set_get_cb(sc_->ctx_, SSLWrap<TLSWrap>::GetSessionCallback);
SSL_CTX_sess_set_new_cb(sc_->ctx_, SSLWrap<TLSWrap>::NewSessionCallback);
@@ -188,7 +191,8 @@ void TLSWrap::Wrap(const FunctionCallbackInfo<Value>& args) {
void TLSWrap::Receive(const FunctionCallbackInfo<Value>& args) {
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK(Buffer::HasInstance(args[0]));
char* data = Buffer::Data(args[0]);
@@ -213,7 +217,8 @@ void TLSWrap::Receive(const FunctionCallbackInfo<Value>& args) {
void TLSWrap::Start(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (wrap->started_)
return env->ThrowError("Already started.");
@@ -731,7 +736,8 @@ int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) {
void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
return env->ThrowTypeError("Bad arguments, expected two booleans");
@@ -763,7 +769,8 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
void TLSWrap::EnableSessionCallbacks(
const FunctionCallbackInfo<Value>& args) {
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (wrap->ssl_ == nullptr) {
return wrap->env()->ThrowTypeError(
"EnableSessionCallbacks after destroySSL");
@@ -777,7 +784,8 @@ void TLSWrap::EnableSessionCallbacks(
void TLSWrap::DestroySSL(const FunctionCallbackInfo<Value>& args) {
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
// Move all writes to pending
wrap->MakePending();
@@ -794,7 +802,8 @@ void TLSWrap::DestroySSL(const FunctionCallbackInfo<Value>& args) {
void TLSWrap::EnableCertCb(const FunctionCallbackInfo<Value>& args) {
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
wrap->WaitForCertCb(OnClientHelloParseEnd, wrap);
}
@@ -809,7 +818,8 @@ void TLSWrap::OnClientHelloParseEnd(void* arg) {
void TLSWrap::GetServername(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK_NE(wrap->ssl_, nullptr);
@@ -826,7 +836,8 @@ void TLSWrap::GetServername(const FunctionCallbackInfo<Value>& args) {
void TLSWrap::SetServername(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TLSWrap* wrap = Unwrap<TLSWrap>(args.Holder());
+ TLSWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
if (args.Length() < 1 || !args[0]->IsString())
return env->ThrowTypeError("First argument should be a string");
@@ -875,6 +886,7 @@ int TLSWrap::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
p->sni_context_.Reset(env->isolate(), ctx);
SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
+ CHECK_NE(sc, nullptr);
p->SetSNIContext(sc);
return SSL_TLSEXT_ERR_OK;
}
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index 6e91dbcd74..319a74fd36 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -90,7 +90,10 @@ void TTYWrap::IsTTY(const FunctionCallbackInfo<Value>& args) {
void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- TTYWrap* wrap = Unwrap<TTYWrap>(args.Holder());
+ TTYWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
CHECK(args[0]->IsArray());
int width, height;
@@ -107,7 +110,10 @@ void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
void TTYWrap::SetRawMode(const FunctionCallbackInfo<Value>& args) {
- TTYWrap* wrap = Unwrap<TTYWrap>(args.Holder());
+ TTYWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int err = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
args.GetReturnValue().Set(err);
}
diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc
index 8c5090ddf7..be141a672c 100644
--- a/src/udp_wrap.cc
+++ b/src/udp_wrap.cc
@@ -139,7 +139,7 @@ void UDPWrap::New(const FunctionCallbackInfo<Value>& args) {
void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {
- int fd = -1;
+ int fd = UV_EBADF;
#if !defined(_WIN32)
HandleScope scope(args.GetIsolate());
UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
@@ -151,7 +151,10 @@ void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {
void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
- UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
+ UDPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
// bind(ip, port, flags)
CHECK_EQ(args.Length(), 3);
@@ -199,7 +202,7 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder()); \
CHECK_EQ(args.Length(), 1); \
int flag = args[0]->Int32Value(); \
- int err = fn(&wrap->handle_, flag); \
+ int err = wrap == nullptr ? UV_EBADF : fn(&wrap->handle_, flag); \
args.GetReturnValue().Set(err); \
}
@@ -213,7 +216,10 @@ X(SetMulticastLoopback, uv_udp_set_multicast_loop)
void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args,
uv_membership membership) {
- UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
+ UDPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
CHECK_EQ(args.Length(), 2);
@@ -246,7 +252,10 @@ void UDPWrap::DropMembership(const FunctionCallbackInfo<Value>& args) {
void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
Environment* env = Environment::GetCurrent(args);
- UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
+ UDPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
// send(req, buffer, port, address, hasCallback)
CHECK(args[0]->IsObject());
@@ -335,7 +344,10 @@ void UDPWrap::Send6(const FunctionCallbackInfo<Value>& args) {
void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {
- UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
+ UDPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int err = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv);
// UV_EALREADY means that the socket is already bound but that's okay
if (err == UV_EALREADY)
@@ -345,7 +357,10 @@ void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {
void UDPWrap::RecvStop(const FunctionCallbackInfo<Value>& args) {
- UDPWrap* wrap = Unwrap<UDPWrap>(args.Holder());
+ UDPWrap* wrap;
+ ASSIGN_OR_RETURN_UNWRAP(&wrap,
+ args.Holder(),
+ args.GetReturnValue().Set(UV_EBADF));
int r = uv_udp_recv_stop(&wrap->handle_);
args.GetReturnValue().Set(r);
}
diff --git a/src/util.h b/src/util.h
index dce6c343b1..406f6a1f36 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,8 +8,20 @@
#include <stddef.h>
#include <stdlib.h>
+#ifdef __APPLE__
+#include <tr1/type_traits>
+#else
+#include <type_traits> // std::remove_reference
+#endif
+
namespace node {
+#ifdef __APPLE__
+template <typename T> using remove_reference = std::tr1::remove_reference<T>;
+#else
+template <typename T> using remove_reference = std::remove_reference<T>;
+#endif
+
#define FIXED_ONE_BYTE_STRING(isolate, string) \
(node::OneByteString((isolate), (string), sizeof(string) - 1))
@@ -53,6 +65,14 @@ namespace node {
#define UNREACHABLE() ABORT()
+#define ASSIGN_OR_RETURN_UNWRAP(ptr, obj, ...) \
+ do { \
+ *ptr = \
+ Unwrap<typename node::remove_reference<decltype(**ptr)>::type>(obj); \
+ if (*ptr == nullptr) \
+ return __VA_ARGS__; \
+ } while (0)
+
// TAILQ-style intrusive list node.
template <typename T>
class ListNode;
diff --git a/test/parallel/test-stream-base-no-abort.js b/test/parallel/test-stream-base-no-abort.js
new file mode 100644
index 0000000000..d2d8702676
--- /dev/null
+++ b/test/parallel/test-stream-base-no-abort.js
@@ -0,0 +1,58 @@
+'use strict';
+
+const async_wrap = process.binding('async_wrap');
+const uv = process.binding('uv');
+const assert = require('assert');
+const common = require('../common');
+const dgram = require('dgram');
+const fs = require('fs');
+const net = require('net');
+const tls = require('tls');
+const providers = Object.keys(async_wrap.Providers);
+var flags = 0;
+
+// Make sure all asserts have run at least once.
+process.on('exit', () => assert.equal(flags, 0b111));
+
+function init(id, provider) {
+ this._external; // Test will abort if nullptr isn't properly checked.
+ switch (providers[provider]) {
+ case 'TCPWRAP':
+ assert.equal(this.fd, uv.UV_EINVAL);
+ flags |= 0b1;
+ break;
+ case 'TLSWRAP':
+ assert.equal(this.fd, uv.UV_EINVAL);
+ flags |= 0b10;
+ break;
+ case 'UDPWRAP':
+ assert.equal(this.fd, uv.UV_EBADF);
+ flags |= 0b100;
+ break;
+ }
+}
+
+async_wrap.setupHooks({ init });
+async_wrap.enable();
+
+const checkTLS = common.mustCall(function checkTLS() {
+ const options = {
+ key: fs.readFileSync(common.fixturesDir + '/keys/ec-key.pem'),
+ cert: fs.readFileSync(common.fixturesDir + '/keys/ec-cert.pem')
+ };
+ const server = tls.createServer(options, () => {})
+ .listen(common.PORT, function() {
+ tls.connect(common.PORT, { rejectUnauthorized: false }, function() {
+ this.destroy();
+ server.close();
+ });
+ });
+});
+
+const checkTCP = common.mustCall(function checkTCP() {
+ net.createServer(() => {}).listen(common.PORT, function() {
+ this.close(checkTLS);
+ });
+});
+
+dgram.createSocket('udp4').close(checkTCP);