Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit 813a45f

Browse files
zcbenzdeepak1556
authored andcommitted
Allocate memory of Buffer with V8's allocator
1 parent a038b70 commit 813a45f

File tree

5 files changed

+86
-48
lines changed

5 files changed

+86
-48
lines changed

src/node_buffer.cc

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ bool zero_fill_all_buffers = false;
5757

5858
namespace {
5959

60-
inline void* BufferMalloc(size_t length) {
61-
return zero_fill_all_buffers ? node::UncheckedCalloc(length) :
62-
node::UncheckedMalloc(length);
60+
inline void* BufferMalloc(v8::Isolate* isolate, size_t length) {
61+
auto* allocator = isolate->GetArrayBufferAllocator();
62+
return zero_fill_all_buffers ? allocator->Allocate(length) :
63+
allocator->AllocateUninitialized(length);
6364
}
6465

6566
} // namespace
@@ -246,7 +247,7 @@ MaybeLocal<Object> New(Isolate* isolate,
246247
char* data = nullptr;
247248

248249
if (length > 0) {
249-
data = static_cast<char*>(BufferMalloc(length));
250+
data = static_cast<char*>(BufferMalloc(isolate, length));
250251

251252
if (data == nullptr)
252253
return Local<Object>();
@@ -255,10 +256,11 @@ MaybeLocal<Object> New(Isolate* isolate,
255256
CHECK(actual <= length);
256257

257258
if (actual == 0) {
258-
free(data);
259+
isolate->GetArrayBufferAllocator()->Free(data, length);
259260
data = nullptr;
260261
} else if (actual < length) {
261-
data = node::Realloc(data, actual);
262+
// We should call realloc here, but v8::ArrayBufferAllocator does not
263+
// provide such ability.
262264
}
263265
}
264266

@@ -267,7 +269,7 @@ MaybeLocal<Object> New(Isolate* isolate,
267269
return scope.Escape(buf);
268270

269271
// Object failed to be created. Clean up resources.
270-
free(data);
272+
isolate->GetArrayBufferAllocator()->Free(data, length);
271273
return Local<Object>();
272274
}
273275

@@ -291,7 +293,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
291293

292294
void* data;
293295
if (length > 0) {
294-
data = BufferMalloc(length);
296+
data = BufferMalloc(env->isolate(), length);
295297
if (data == nullptr)
296298
return Local<Object>();
297299
} else {
@@ -307,7 +309,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
307309

308310
if (ui.IsEmpty()) {
309311
// Object failed to be created. Clean up resources.
310-
free(data);
312+
env->isolate()->GetArrayBufferAllocator()->Free(data, length);
311313
}
312314

313315
return scope.Escape(ui.FromMaybe(Local<Uint8Array>()));
@@ -332,10 +334,11 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
332334
return Local<Object>();
333335
}
334336

337+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
335338
void* new_data;
336339
if (length > 0) {
337340
CHECK_NE(data, nullptr);
338-
new_data = node::UncheckedMalloc(length);
341+
new_data = allocator->AllocateUninitialized(length);
339342
if (new_data == nullptr)
340343
return Local<Object>();
341344
memcpy(new_data, data, length);
@@ -352,7 +355,7 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
352355

353356
if (ui.IsEmpty()) {
354357
// Object failed to be created. Clean up resources.
355-
free(new_data);
358+
allocator->Free(new_data, length);
356359
}
357360

358361
return scope.Escape(ui.FromMaybe(Local<Uint8Array>()));

src/node_crypto.cc

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,7 +2114,8 @@ void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
21142114
int slen = i2d_SSL_SESSION(sess, nullptr);
21152115
CHECK_GT(slen, 0);
21162116

2117-
char* sbuf = Malloc(slen);
2117+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
2118+
char* sbuf = static_cast<char*>(allocator->AllocateUninitialized(slen));
21182119
unsigned char* p = reinterpret_cast<unsigned char*>(sbuf);
21192120
i2d_SSL_SESSION(sess, &p);
21202121
args.GetReturnValue().Set(Buffer::New(env, sbuf, slen).ToLocalChecked());
@@ -3894,8 +3895,9 @@ bool CipherBase::Update(const char* data,
38943895
auth_tag_len_ = 0;
38953896
}
38963897

3898+
auto* allocator = env()->isolate()->GetArrayBufferAllocator();
38973899
*out_len = len + EVP_CIPHER_CTX_block_size(ctx_);
3898-
*out = Malloc<unsigned char>(static_cast<size_t>(*out_len));
3900+
*out = static_cast<unsigned char*>(allocator->AllocateUninitialized(*out_len));
38993901
return EVP_CipherUpdate(ctx_,
39003902
*out,
39013903
out_len,
@@ -3929,7 +3931,8 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
39293931
}
39303932

39313933
if (!r) {
3932-
free(out);
3934+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
3935+
allocator->Free(out, out_len);
39333936
return ThrowCryptoError(env,
39343937
ERR_get_error(),
39353938
"Trying to add data in unsupported state");
@@ -3965,8 +3968,9 @@ bool CipherBase::Final(unsigned char** out, int *out_len) {
39653968
if (ctx_ == nullptr)
39663969
return false;
39673970

3968-
*out = Malloc<unsigned char>(
3969-
static_cast<size_t>(EVP_CIPHER_CTX_block_size(ctx_)));
3971+
auto* allocator = env()->isolate()->GetArrayBufferAllocator();
3972+
*out = static_cast<unsigned char*>(allocator->AllocateUninitialized(
3973+
EVP_CIPHER_CTX_block_size(ctx_)));
39703974
int r = EVP_CipherFinal_ex(ctx_, *out, out_len);
39713975

39723976
if (r == 1 && kind_ == kCipher && IsAuthenticatedMode()) {
@@ -3998,7 +4002,8 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
39984002
bool r = cipher->Final(&out_value, &out_len);
39994003

40004004
if (out_len <= 0 || !r) {
4001-
free(out_value);
4005+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
4006+
allocator->Free(out_value, out_len);
40024007
out_value = nullptr;
40034008
out_len = 0;
40044009
if (!r) {
@@ -4712,7 +4717,8 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
47124717
template <PublicKeyCipher::Operation operation,
47134718
PublicKeyCipher::EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
47144719
PublicKeyCipher::EVP_PKEY_cipher_t EVP_PKEY_cipher>
4715-
bool PublicKeyCipher::Cipher(const char* key_pem,
4720+
bool PublicKeyCipher::Cipher(Environment* env,
4721+
const char* key_pem,
47164722
int key_pem_len,
47174723
const char* passphrase,
47184724
int padding,
@@ -4725,6 +4731,7 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
47254731
BIO* bp = nullptr;
47264732
X509* x509 = nullptr;
47274733
bool fatal = true;
4734+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
47284735

47294736
bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
47304737
if (bp == nullptr)
@@ -4777,7 +4784,7 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
47774784
if (EVP_PKEY_cipher(ctx, nullptr, out_len, data, len) <= 0)
47784785
goto exit;
47794786

4780-
*out = Malloc<unsigned char>(*out_len);
4787+
*out = static_cast<unsigned char*>(allocator->AllocateUninitialized(*out_len));
47814788

47824789
if (EVP_PKEY_cipher(ctx, *out, out_len, data, len) <= 0)
47834790
goto exit;
@@ -4822,6 +4829,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
48224829
ClearErrorOnReturn clear_error_on_return;
48234830

48244831
bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
4832+
env,
48254833
kbuf,
48264834
klen,
48274835
args.Length() >= 3 && !args[2]->IsNull() ? *passphrase : nullptr,
@@ -4832,7 +4840,8 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
48324840
&out_len);
48334841

48344842
if (out_len == 0 || !r) {
4835-
free(out_value);
4843+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
4844+
allocator->Free(out_value, out_len);
48364845
out_value = nullptr;
48374846
out_len = 0;
48384847
if (!r) {
@@ -5037,7 +5046,8 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
50375046
const BIGNUM* pub_key;
50385047
DH_get0_key(diffieHellman->dh, &pub_key, nullptr);
50395048
size_t size = BN_num_bytes(pub_key);
5040-
char* data = Malloc(size);
5049+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
5050+
char* data = static_cast<char*>(allocator->AllocateUninitialized(size));
50415051
BN_bn2bin(pub_key, reinterpret_cast<unsigned char*>(data));
50425052
args.GetReturnValue().Set(Buffer::New(env, data, size).ToLocalChecked());
50435053
}
@@ -5056,7 +5066,8 @@ void DiffieHellman::GetField(const FunctionCallbackInfo<Value>& args,
50565066
if (num == nullptr) return env->ThrowError(err_if_null);
50575067

50585068
size_t size = BN_num_bytes(num);
5059-
char* data = Malloc(size);
5069+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
5070+
char* data = static_cast<char*>(allocator->AllocateUninitialized(size));
50605071
BN_bn2bin(num, reinterpret_cast<unsigned char*>(data));
50615072
args.GetReturnValue().Set(Buffer::New(env, data, size).ToLocalChecked());
50625073
}
@@ -5121,7 +5132,8 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
51215132
}
51225133

51235134
int dataSize = DH_size(diffieHellman->dh);
5124-
char* data = Malloc(dataSize);
5135+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
5136+
char* data = static_cast<char*>(allocator->AllocateUninitialized(dataSize));
51255137

51265138
int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
51275139
key,
@@ -5133,7 +5145,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
51335145

51345146
checked = DH_check_pub_key(diffieHellman->dh, key, &checkResult);
51355147
BN_free(key);
5136-
free(data);
5148+
allocator->Free(data, dataSize);
51375149

51385150
if (!checked) {
51395151
return ThrowCryptoError(env, ERR_get_error(), "Invalid Key");
@@ -5338,14 +5350,15 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
53385350
return;
53395351

53405352
// NOTE: field_size is in bits
5353+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
53415354
int field_size = EC_GROUP_get_degree(ecdh->group_);
53425355
size_t out_len = (field_size + 7) / 8;
5343-
char* out = node::Malloc(out_len);
5356+
char* out = static_cast<char*>(allocator->AllocateUninitialized(out_len));
53445357

53455358
int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
53465359
EC_POINT_free(pub);
53475360
if (!r) {
5348-
free(out);
5361+
allocator->Free(out, out_len);
53495362
return env->ThrowError("Failed to compute ECDH key");
53505363
}
53515364

@@ -5375,11 +5388,13 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
53755388
if (size == 0)
53765389
return env->ThrowError("Failed to get public key length");
53775390

5378-
unsigned char* out = node::Malloc<unsigned char>(size);
5391+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
5392+
unsigned char* out =
5393+
static_cast<unsigned char*>(allocator->AllocateUninitialized(size));
53795394

53805395
int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
53815396
if (r != size) {
5382-
free(out);
5397+
allocator->Free(out, size);
53835398
return env->ThrowError("Failed to get public key");
53845399
}
53855400

@@ -5399,11 +5414,13 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
53995414
if (b == nullptr)
54005415
return env->ThrowError("Failed to get ECDH private key");
54015416

5417+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
54025418
int size = BN_num_bytes(b);
5403-
unsigned char* out = node::Malloc<unsigned char>(size);
5419+
unsigned char* out =
5420+
static_cast<unsigned char*>(allocator->AllocateUninitialized(size));
54045421

54055422
if (size != BN_bn2bin(b, out)) {
5406-
free(out);
5423+
allocator->Free(out, size);
54075424
return env->ThrowError("Failed to convert ECDH private key to Buffer");
54085425
}
54095426

@@ -5532,7 +5549,8 @@ class PBKDF2Request : public AsyncWrap {
55325549
saltlen_(saltlen),
55335550
salt_(salt),
55345551
keylen_(keylen),
5535-
key_(node::Malloc(keylen)),
5552+
key_(static_cast<char*>(env->isolate()->GetArrayBufferAllocator()->
5553+
AllocateUninitialized(keylen))),
55365554
iter_(iter) {
55375555
Wrap(object, this);
55385556
}
@@ -5546,7 +5564,7 @@ class PBKDF2Request : public AsyncWrap {
55465564
salt_ = nullptr;
55475565
saltlen_ = 0;
55485566

5549-
free(key_);
5567+
env()->isolate()->GetArrayBufferAllocator()->Free(key_, keylen_);
55505568
key_ = nullptr;
55515569
keylen_ = 0;
55525570

@@ -5738,9 +5756,10 @@ class RandomBytesRequest : public AsyncWrap {
57385756
}
57395757

57405758
inline void release() {
5759+
size_t free_size = size_;
57415760
size_ = 0;
57425761
if (free_mode_ == FREE_DATA) {
5743-
free(data_);
5762+
env()->isolate()->GetArrayBufferAllocator()->Free(data_, free_size);
57445763
data_ = nullptr;
57455764
}
57465765
}
@@ -5857,7 +5876,8 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
58575876

58585877
Local<Object> obj = env->randombytes_constructor_template()->
58595878
NewInstance(env->context()).ToLocalChecked();
5860-
char* data = node::Malloc(size);
5879+
char* data = static_cast<char*>(
5880+
env->isolate()->GetArrayBufferAllocator()->AllocateUninitialized(size));
58615881
std::unique_ptr<RandomBytesRequest> req(
58625882
new RandomBytesRequest(env,
58635883
obj,
@@ -6057,10 +6077,11 @@ void VerifySpkac(const FunctionCallbackInfo<Value>& args) {
60576077
}
60586078

60596079

6060-
char* ExportPublicKey(const char* data, int len, size_t* size) {
6080+
char* ExportPublicKey(Environment* env, const char* data, int len, size_t* size) {
60616081
char* buf = nullptr;
60626082
EVP_PKEY* pkey = nullptr;
60636083
NETSCAPE_SPKI* spki = nullptr;
6084+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
60646085

60656086
BIO* bio = BIO_new(BIO_s_mem());
60666087
if (bio == nullptr)
@@ -6081,7 +6102,7 @@ char* ExportPublicKey(const char* data, int len, size_t* size) {
60816102
BIO_get_mem_ptr(bio, &ptr);
60826103

60836104
*size = ptr->length;
6084-
buf = Malloc(*size);
6105+
buf = static_cast<char*>(allocator->AllocateUninitialized(*size));
60856106
memcpy(buf, ptr->data, *size);
60866107

60876108
exit:
@@ -6109,7 +6130,7 @@ void ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
61096130
CHECK_NE(data, nullptr);
61106131

61116132
size_t pkey_size;
6112-
char* pkey = ExportPublicKey(data, length, &pkey_size);
6133+
char* pkey = ExportPublicKey(env, data, length, &pkey_size);
61136134
if (pkey == nullptr)
61146135
return args.GetReturnValue().SetEmptyString();
61156136

src/node_crypto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ class PublicKeyCipher {
640640
template <Operation operation,
641641
EVP_PKEY_cipher_init_t EVP_PKEY_cipher_init,
642642
EVP_PKEY_cipher_t EVP_PKEY_cipher>
643-
static bool Cipher(const char* key_pem,
643+
static bool Cipher(Environment* env,
644+
const char* key_pem,
644645
int key_pem_len,
645646
const char* passphrase,
646647
int padding,

src/stream_base.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,26 @@ void StreamResource::ClearError() {
347347

348348

349349
uv_buf_t StreamListener::OnStreamAlloc(size_t suggested_size) {
350-
return uv_buf_init(Malloc(suggested_size), suggested_size);
350+
CHECK_NE(stream_, nullptr);
351+
StreamBase* stream = static_cast<StreamBase*>(stream_);
352+
Environment* env = stream->stream_env();
353+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
354+
return uv_buf_init(
355+
static_cast<char*>(allocator->AllocateUninitialized(suggested_size)),
356+
suggested_size);
351357
}
352358

353359

354360
void EmitToJSStreamListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
355361
CHECK_NE(stream_, nullptr);
356362
StreamBase* stream = static_cast<StreamBase*>(stream_);
357363
Environment* env = stream->stream_env();
364+
auto* allocator = env->isolate()->GetArrayBufferAllocator();
358365
HandleScope handle_scope(env->isolate());
359366
Context::Scope context_scope(env->context());
360367

361368
if (nread <= 0) {
362-
free(buf.base);
369+
allocator->Free(buf.base, buf.len);
363370
if (nread < 0)
364371
stream->CallJSOnreadMethod(nread, Local<Object>());
365372
return;

0 commit comments

Comments
 (0)