From 2ee31aa261533f1c6b684108522ce70f0ff62ff2 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 10 Jul 2017 12:56:37 +0200 Subject: [PATCH] src: remove extra heap allocations in CipherBase Don't allocate + copy + free; allocate and fill in place, then hand off the pointer to Buffer::New(). Avoids unnecessary heap allocations in the following methods: - crypto.Cipher#final() - crypto.Cipher#update() - crypto.Cipheriv#final() - crypto.Cipheriv#update() - crypto.Decipher#final() - crypto.Decipher#update() - crypto.Decipheriv#final() - crypto.Decipheriv#update() - crypto.privateDecrypt() - crypto.privateEncrypt() - crypto.publicDecrypt() - crypto.publicEncrypt() PR-URL: https://github.com/nodejs/node/pull/14122 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- src/node_crypto.cc | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 36102e53f9c045..26445f1b833686 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3561,7 +3561,7 @@ bool CipherBase::Update(const char* data, } *out_len = len + EVP_CIPHER_CTX_block_size(&ctx_); - *out = new unsigned char[*out_len]; + *out = Malloc(static_cast(*out_len)); return EVP_CipherUpdate(&ctx_, *out, out_len, @@ -3595,7 +3595,7 @@ void CipherBase::Update(const FunctionCallbackInfo& args) { } if (!r) { - delete[] out; + free(out); return ThrowCryptoError(env, ERR_get_error(), "Trying to add data in unsupported state"); @@ -3603,9 +3603,7 @@ void CipherBase::Update(const FunctionCallbackInfo& args) { CHECK(out != nullptr || out_len == 0); Local buf = - Buffer::Copy(env, reinterpret_cast(out), out_len).ToLocalChecked(); - if (out) - delete[] out; + Buffer::New(env, reinterpret_cast(out), out_len).ToLocalChecked(); args.GetReturnValue().Set(buf); } @@ -3633,7 +3631,8 @@ bool CipherBase::Final(unsigned char** out, int *out_len) { if (!initialised_) return false; - *out = new unsigned char[EVP_CIPHER_CTX_block_size(&ctx_)]; + *out = Malloc( + static_cast(EVP_CIPHER_CTX_block_size(&ctx_))); int r = EVP_CipherFinal_ex(&ctx_, *out, out_len); if (r && kind_ == kCipher) { @@ -3670,7 +3669,7 @@ void CipherBase::Final(const FunctionCallbackInfo& args) { bool r = cipher->Final(&out_value, &out_len); if (out_len <= 0 || !r) { - delete[] out_value; + free(out_value); out_value = nullptr; out_len = 0; if (!r) { @@ -3684,12 +3683,11 @@ void CipherBase::Final(const FunctionCallbackInfo& args) { } } - Local buf = Buffer::Copy( + Local buf = Buffer::New( env, reinterpret_cast(out_value), out_len).ToLocalChecked(); args.GetReturnValue().Set(buf); - delete[] out_value; } @@ -4560,7 +4558,7 @@ bool PublicKeyCipher::Cipher(const char* key_pem, if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0) goto exit; - *out = new unsigned char[*out_len]; + *out = Malloc(*out_len); if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0) goto exit; @@ -4615,7 +4613,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { &out_len); if (out_len == 0 || !r) { - delete[] out_value; + free(out_value); out_value = nullptr; out_len = 0; if (!r) { @@ -4624,12 +4622,10 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { } } - Local vbuf = Buffer::Copy( - env, - reinterpret_cast(out_value), - out_len).ToLocalChecked(); + Local vbuf = + Buffer::New(env, reinterpret_cast(out_value), out_len) + .ToLocalChecked(); args.GetReturnValue().Set(vbuf); - delete[] out_value; }