diff options
-rw-r--r-- | src/base-object-inl.h | 4 | ||||
-rw-r--r-- | src/fs_event_wrap.cc | 6 | ||||
-rw-r--r-- | src/handle_wrap.cc | 12 | ||||
-rw-r--r-- | src/js_stream.cc | 23 | ||||
-rw-r--r-- | src/node_contextify.cc | 23 | ||||
-rw-r--r-- | src/node_crypto.cc | 276 | ||||
-rw-r--r-- | src/node_http_parser.cc | 24 | ||||
-rw-r--r-- | src/node_internals.h | 2 | ||||
-rw-r--r-- | src/node_stat_watcher.cc | 6 | ||||
-rw-r--r-- | src/node_wrap.h | 2 | ||||
-rw-r--r-- | src/node_zlib.cc | 15 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 18 | ||||
-rw-r--r-- | src/process_wrap.cc | 7 | ||||
-rw-r--r-- | src/signal_wrap.cc | 6 | ||||
-rw-r--r-- | src/stream_base-inl.h | 16 | ||||
-rw-r--r-- | src/stream_base.cc | 3 | ||||
-rw-r--r-- | src/stream_wrap.cc | 6 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 46 | ||||
-rw-r--r-- | src/tls_wrap.cc | 28 | ||||
-rw-r--r-- | src/tty_wrap.cc | 10 | ||||
-rw-r--r-- | src/udp_wrap.cc | 29 | ||||
-rw-r--r-- | src/util.h | 20 | ||||
-rw-r--r-- | test/parallel/test-stream-base-no-abort.js | 58 |
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); |