Skip to content

Commit 6a0eb9f

Browse files
addaleaxMylesBorins
authored andcommitted
src: provide allocation + nullptr check shortcuts
Provide shortcut `node::CheckedMalloc()` and friends that replace `node::Malloc()` + `CHECK_NE(·, nullptr);` combinations in a few places. Backport-PR-URL: #16587 PR-URL: #8482 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
1 parent 4aec8cf commit 6a0eb9f

13 files changed

+67
-49
lines changed

src/cares_wrap.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) {
175175

176176
/* Allocates and returns a new node_ares_task */
177177
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
178-
auto task = node::Malloc<node_ares_task>(1);
178+
auto task = node::UncheckedMalloc<node_ares_task>(1);
179179

180180
if (task == nullptr) {
181181
/* Out of memory. */

src/node.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,9 @@ void* ArrayBufferAllocator::Allocate(size_t size) {
10541054
if (env_ == nullptr ||
10551055
!env_->array_buffer_allocator_info()->no_zero_fill() ||
10561056
zero_fill_all_buffers)
1057-
return node::Calloc(size);
1057+
return node::UncheckedCalloc(size);
10581058
env_->array_buffer_allocator_info()->reset_fill_flag();
1059-
return node::Malloc(size);
1059+
return node::UncheckedMalloc(size);
10601060
}
10611061

10621062
static bool DomainHasErrorHandler(const Environment* env,

src/node_buffer.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ bool zero_fill_all_buffers = false;
5656
namespace {
5757

5858
inline void* BufferMalloc(size_t length) {
59-
return zero_fill_all_buffers ? node::Calloc(length) :
60-
node::Malloc(length);
59+
return zero_fill_all_buffers ? node::UncheckedCalloc(length) :
60+
node::UncheckedMalloc(length);
6161
}
6262

6363
} // namespace
@@ -253,7 +253,6 @@ MaybeLocal<Object> New(Isolate* isolate,
253253
data = nullptr;
254254
} else if (actual < length) {
255255
data = node::Realloc(data, actual);
256-
CHECK_NE(data, nullptr);
257256
}
258257
}
259258

@@ -331,7 +330,7 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
331330
void* new_data;
332331
if (length > 0) {
333332
CHECK_NE(data, nullptr);
334-
new_data = node::Malloc(length);
333+
new_data = node::UncheckedMalloc(length);
335334
if (new_data == nullptr)
336335
return Local<Object>();
337336
memcpy(new_data, data, length);
@@ -1069,7 +1068,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
10691068
offset,
10701069
is_forward);
10711070
} else if (enc == LATIN1) {
1072-
uint8_t* needle_data = node::Malloc<uint8_t>(needle_length);
1071+
uint8_t* needle_data = node::UncheckedMalloc<uint8_t>(needle_length);
10731072
if (needle_data == nullptr) {
10741073
return args.GetReturnValue().Set(-1);
10751074
}

src/node_crypto.cc

-17
Original file line numberDiff line numberDiff line change
@@ -2387,7 +2387,6 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
23872387

23882388
// OpenSSL takes control of the pointer after accepting it
23892389
char* data = node::Malloc(len);
2390-
CHECK_NE(data, nullptr);
23912390
memcpy(data, resp, len);
23922391

23932392
if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
@@ -3467,7 +3466,6 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
34673466
return false;
34683467
*out_len = auth_tag_len_;
34693468
*out = node::Malloc(auth_tag_len_);
3470-
CHECK_NE(*out, nullptr);
34713469
memcpy(*out, auth_tag_, auth_tag_len_);
34723470
return true;
34733471
}
@@ -5139,7 +5137,6 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
51395137
int field_size = EC_GROUP_get_degree(ecdh->group_);
51405138
size_t out_len = (field_size + 7) / 8;
51415139
char* out = node::Malloc(out_len);
5142-
CHECK_NE(out, nullptr);
51435140

51445141
int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
51455142
EC_POINT_free(pub);
@@ -5175,7 +5172,6 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
51755172
return env->ThrowError("Failed to get public key length");
51765173

51775174
unsigned char* out = node::Malloc<unsigned char>(size);
5178-
CHECK_NE(out, nullptr);
51795175

51805176
int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
51815177
if (r != size) {
@@ -5201,7 +5197,6 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
52015197

52025198
int size = BN_num_bytes(b);
52035199
unsigned char* out = node::Malloc<unsigned char>(size);
5204-
CHECK_NE(out, nullptr);
52055200

52065201
if (size != BN_bn2bin(b, out)) {
52075202
free(out);
@@ -5335,8 +5330,6 @@ class PBKDF2Request : public AsyncWrap {
53355330
keylen_(keylen),
53365331
key_(node::Malloc(keylen)),
53375332
iter_(iter) {
5338-
if (key() == nullptr)
5339-
FatalError("node::PBKDF2Request()", "Out of Memory");
53405333
Wrap(object, this);
53415334
}
53425335

@@ -5497,9 +5490,6 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
54975490
THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt");
54985491

54995492
pass = node::Malloc(passlen);
5500-
if (pass == nullptr) {
5501-
FatalError("node::PBKDF2()", "Out of Memory");
5502-
}
55035493
memcpy(pass, Buffer::Data(args[0]), passlen);
55045494

55055495
saltlen = Buffer::Length(args[1]);
@@ -5509,9 +5499,6 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
55095499
}
55105500

55115501
salt = node::Malloc(saltlen);
5512-
if (salt == nullptr) {
5513-
FatalError("node::PBKDF2()", "Out of Memory");
5514-
}
55155502
memcpy(salt, Buffer::Data(args[1]), saltlen);
55165503

55175504
if (!args[2]->IsNumber()) {
@@ -5602,8 +5589,6 @@ class RandomBytesRequest : public AsyncWrap {
56025589
error_(0),
56035590
size_(size),
56045591
data_(node::Malloc(size)) {
5605-
if (data() == nullptr)
5606-
FatalError("node::RandomBytesRequest()", "Out of Memory");
56075592
Wrap(object, this);
56085593
}
56095594

@@ -5830,8 +5815,6 @@ void GetCurves(const FunctionCallbackInfo<Value>& args) {
58305815
if (num_curves) {
58315816
curves = node::Malloc<EC_builtin_curve>(num_curves);
58325817

5833-
CHECK_NE(curves, nullptr);
5834-
58355818
if (EC_get_builtin_curves(curves, num_curves)) {
58365819
for (size_t i = 0; i < num_curves; i++) {
58375820
arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid)));

src/node_internals.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
199199

200200
virtual void* Allocate(size_t size); // Defined in src/node.cc
201201
virtual void* AllocateUninitialized(size_t size)
202-
{ return node::Malloc(size); }
202+
{ return node::UncheckedMalloc(size); }
203203
virtual void Free(void* data, size_t) { free(data); }
204204

205205
private:

src/stream_wrap.cc

+1-7
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,6 @@ void StreamWrap::OnAlloc(uv_handle_t* handle,
150150
void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) {
151151
buf->base = node::Malloc(size);
152152
buf->len = size;
153-
154-
if (buf->base == nullptr && size > 0) {
155-
FatalError(
156-
"node::StreamWrap::DoAlloc(size_t, uv_buf_t*, void*)",
157-
"Out Of Memory");
158-
}
159153
}
160154

161155

@@ -204,8 +198,8 @@ void StreamWrap::OnReadImpl(ssize_t nread,
204198
return;
205199
}
206200

207-
char* base = node::Realloc(buf->base, nread);
208201
CHECK_LE(static_cast<size_t>(nread), buf->len);
202+
char* base = node::Realloc(buf->base, nread);
209203

210204
if (pending == UV_TCP) {
211205
pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(env, wrap);

src/string_bytes.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ExternString: public ResourceType {
5353
if (length == 0)
5454
return scope.Escape(String::Empty(isolate));
5555

56-
TypeName* new_data = node::Malloc<TypeName>(length);
56+
TypeName* new_data = node::UncheckedMalloc<TypeName>(length);
5757
if (new_data == nullptr) {
5858
return Local<String>();
5959
}
@@ -609,7 +609,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
609609

610610
case ASCII:
611611
if (contains_non_ascii(buf, buflen)) {
612-
char* out = node::Malloc(buflen);
612+
char* out = node::UncheckedMalloc(buflen);
613613
if (out == nullptr) {
614614
return Local<String>();
615615
}
@@ -644,7 +644,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
644644

645645
case BASE64: {
646646
size_t dlen = base64_encoded_size(buflen);
647-
char* dst = node::Malloc(dlen);
647+
char* dst = node::UncheckedMalloc(dlen);
648648
if (dst == nullptr) {
649649
return Local<String>();
650650
}
@@ -663,7 +663,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,
663663

664664
case HEX: {
665665
size_t dlen = buflen * 2;
666-
char* dst = node::Malloc(dlen);
666+
char* dst = node::UncheckedMalloc(dlen);
667667
if (dst == nullptr) {
668668
return Local<String>();
669669
}

src/tls_wrap.cc

-1
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,6 @@ void TLSWrap::OnDestructImpl(void* ctx) {
664664

665665
void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) {
666666
buf->base = node::Malloc(suggested_size);
667-
CHECK_NE(buf->base, nullptr);
668667
buf->len = suggested_size;
669668
}
670669

src/udp_wrap.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,6 @@ void UDPWrap::OnAlloc(uv_handle_t* handle,
375375
uv_buf_t* buf) {
376376
buf->base = node::Malloc(suggested_size);
377377
buf->len = suggested_size;
378-
379-
if (buf->base == nullptr && suggested_size > 0) {
380-
FatalError("node::UDPWrap::OnAlloc(uv_handle_t*, size_t, uv_buf_t*)",
381-
"Out Of Memory");
382-
}
383378
}
384379

385380

@@ -415,7 +410,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
415410
return;
416411
}
417412

418-
char* base = node::Realloc(buf->base, nread);
413+
char* base = node::UncheckedRealloc(buf->base, nread);
419414
argv[2] = Buffer::New(env, base, nread).ToLocalChecked();
420415
argv[3] = AddressToJS(env, addr);
421416
wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv);

src/util-inl.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) {
336336
// nullptr for zero-sized allocation requests. Normalize by always using
337337
// a nullptr.
338338
template <typename T>
339-
T* Realloc(T* pointer, size_t n) {
339+
T* UncheckedRealloc(T* pointer, size_t n) {
340340
size_t full_size = MultiplyWithOverflowCheck(sizeof(T), n);
341341

342342
if (full_size == 0) {
@@ -349,18 +349,39 @@ T* Realloc(T* pointer, size_t n) {
349349

350350
// As per spec realloc behaves like malloc if passed nullptr.
351351
template <typename T>
352-
T* Malloc(size_t n) {
352+
T* UncheckedMalloc(size_t n) {
353353
if (n == 0) n = 1;
354-
return Realloc<T>(nullptr, n);
354+
return UncheckedRealloc<T>(nullptr, n);
355355
}
356356

357357
template <typename T>
358-
T* Calloc(size_t n) {
358+
T* UncheckedCalloc(size_t n) {
359359
if (n == 0) n = 1;
360360
MultiplyWithOverflowCheck(sizeof(T), n);
361361
return static_cast<T*>(calloc(n, sizeof(T)));
362362
}
363363

364+
template <typename T>
365+
T* Realloc(T* pointer, size_t n) {
366+
T* ret = UncheckedRealloc(pointer, n);
367+
if (n > 0) CHECK_NE(ret, nullptr);
368+
return ret;
369+
}
370+
371+
template <typename T>
372+
T* Malloc(size_t n) {
373+
T* ret = UncheckedMalloc<T>(n);
374+
if (n > 0) CHECK_NE(ret, nullptr);
375+
return ret;
376+
}
377+
378+
template <typename T>
379+
T* Calloc(size_t n) {
380+
T* ret = UncheckedCalloc<T>(n);
381+
if (n > 0) CHECK_NE(ret, nullptr);
382+
return ret;
383+
}
384+
364385
} // namespace node
365386

366387
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

src/util.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "util.h"
22
#include "string_bytes.h"
33
#include "node_buffer.h"
4+
#include "node_internals.h"
45
#include <stdio.h>
56

67
namespace node {

src/util.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ namespace node {
3232
// nullptr for zero-sized allocation requests. Normalize by always using
3333
// a nullptr.
3434
template <typename T>
35+
inline T* UncheckedRealloc(T* pointer, size_t n);
36+
template <typename T>
37+
inline T* UncheckedMalloc(size_t n);
38+
template <typename T>
39+
inline T* UncheckedCalloc(size_t n);
40+
41+
// Same things, but aborts immediately instead of returning nullptr when
42+
// no memory is available.
43+
template <typename T>
3544
inline T* Realloc(T* pointer, size_t n);
3645
template <typename T>
3746
inline T* Malloc(size_t n);
@@ -41,6 +50,8 @@ inline T* Calloc(size_t n);
4150
// Shortcuts for char*.
4251
inline char* Malloc(size_t n) { return Malloc<char>(n); }
4352
inline char* Calloc(size_t n) { return Calloc<char>(n); }
53+
inline char* UncheckedMalloc(size_t n) { return UncheckedMalloc<char>(n); }
54+
inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc<char>(n); }
4455

4556
#ifdef __GNUC__
4657
#define NO_RETURN __attribute__((noreturn))
@@ -302,7 +313,6 @@ class MaybeStackBuffer {
302313
buf_ = buf_st_;
303314
} else {
304315
buf_ = Malloc<T>(storage);
305-
CHECK_NE(buf_, nullptr);
306316
}
307317

308318
// Remember how much was allocated to check against that in SetLength().

test/cctest/test_util.cc

+16
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,19 @@ TEST(UtilTest, Calloc) {
105105
EXPECT_NE(nullptr, Calloc(0));
106106
EXPECT_NE(nullptr, Calloc(1));
107107
}
108+
109+
TEST(UtilTest, UncheckedMalloc) {
110+
using node::UncheckedMalloc;
111+
EXPECT_NE(nullptr, UncheckedMalloc<char>(0));
112+
EXPECT_NE(nullptr, UncheckedMalloc<char>(1));
113+
EXPECT_NE(nullptr, UncheckedMalloc(0));
114+
EXPECT_NE(nullptr, UncheckedMalloc(1));
115+
}
116+
117+
TEST(UtilTest, UncheckedCalloc) {
118+
using node::UncheckedCalloc;
119+
EXPECT_NE(nullptr, UncheckedCalloc<char>(0));
120+
EXPECT_NE(nullptr, UncheckedCalloc<char>(1));
121+
EXPECT_NE(nullptr, UncheckedCalloc(0));
122+
EXPECT_NE(nullptr, UncheckedCalloc(1));
123+
}

0 commit comments

Comments
 (0)