Browse Source

src: no abort from getter if object isn't wrapped

v8::Object::GetAlignedPointerFromInternalField() returns a random value
if Wrap() hasn't been run on the object handle. Causing v8 to abort if
certain getters are accessed. It's possible to access these getters and
functions during class construction through the AsyncWrap init()
callback, and also possible in a subset of those scenarios while running
the persistent handle visitor.

Mitigate this issue by manually setting the internal aligned pointer
field to nullptr in the BaseObject constructor and add necessary logic
to return appropriate values when nullptr is encountered.

PR-URL: https://github.com/nodejs/node/pull/6184
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
v7.x
Trevor Norris 9 years ago
parent
commit
c0e6c668e6
  1. 4
      src/base-object-inl.h
  2. 6
      src/fs_event_wrap.cc
  3. 12
      src/handle_wrap.cc
  4. 23
      src/js_stream.cc
  5. 23
      src/node_contextify.cc
  6. 276
      src/node_crypto.cc
  7. 24
      src/node_http_parser.cc
  8. 2
      src/node_internals.h
  9. 6
      src/node_stat_watcher.cc
  10. 2
      src/node_wrap.h
  11. 15
      src/node_zlib.cc
  12. 18
      src/pipe_wrap.cc
  13. 7
      src/process_wrap.cc
  14. 6
      src/signal_wrap.cc
  15. 16
      src/stream_base-inl.h
  16. 3
      src/stream_base.cc
  17. 6
      src/stream_wrap.cc
  18. 46
      src/tcp_wrap.cc
  19. 28
      src/tls_wrap.cc
  20. 10
      src/tty_wrap.cc
  21. 29
      src/udp_wrap.cc
  22. 20
      src/util.h
  23. 58
      test/parallel/test-stream-base-no-abort.js

4
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);
}

6
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;

12
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))

23
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);
}

23
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();

276
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");

24
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(),

2
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);

6
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);

2
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());
}, {});

15
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);
}

18
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());

7
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);

6
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);
}

16
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())

3
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.

6
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())

46
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());

28
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;
}

10
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);
}

29
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);
}

20
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;

58
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);
Loading…
Cancel
Save