Skip to content

Commit 3fed9fb

Browse files
authored
src: throw RangeError on failed ArrayBuffer BackingStore allocation
This also updates `ERR_MEMORY_ALLOCATION_FAILED` to be a RangeError, aligning with V8's OutOfMemory error type. PR-URL: #61480 Refs: https://github.com/nodejs/node/blob/c755b0113ce0cb6d83baf2cf070ba381a5673db2/deps/v8/src/builtins/builtins-typed-array.cc#L584 Refs: https://tc39.es/ecma262/#sec-sharedarraybuffer.prototype.grow Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 680ee6e commit 3fed9fb

File tree

4 files changed

+53
-15
lines changed

4 files changed

+53
-15
lines changed

src/encoding_binding.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace encoding_binding {
1717
using v8::ArrayBuffer;
1818
using v8::BackingStore;
1919
using v8::BackingStoreInitializationMode;
20+
using v8::BackingStoreOnFailureMode;
2021
using v8::Context;
2122
using v8::FunctionCallbackInfo;
2223
using v8::HandleScope;
@@ -317,9 +318,15 @@ void BindingData::EncodeUtf8String(const FunctionCallbackInfo<Value>& args) {
317318
Local<ArrayBuffer> ab;
318319
{
319320
std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore(
320-
isolate, length, BackingStoreInitializationMode::kUninitialized);
321+
isolate,
322+
length,
323+
BackingStoreInitializationMode::kUninitialized,
324+
BackingStoreOnFailureMode::kReturnNull);
321325

322-
CHECK(bs);
326+
if (!bs) [[unlikely]] {
327+
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
328+
return;
329+
}
323330

324331
// We are certain that `data` is sufficiently large
325332
str->WriteUtf8V2(isolate,

src/node_blob.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ using v8::ArrayBuffer;
2222
using v8::ArrayBufferView;
2323
using v8::BackingStore;
2424
using v8::BackingStoreInitializationMode;
25+
using v8::BackingStoreOnFailureMode;
2526
using v8::Context;
2627
using v8::Function;
2728
using v8::FunctionCallbackInfo;
@@ -83,7 +84,14 @@ void Concat(const FunctionCallbackInfo<Value>& args) {
8384
}
8485

8586
std::shared_ptr<BackingStore> store = ArrayBuffer::NewBackingStore(
86-
isolate, total, BackingStoreInitializationMode::kUninitialized);
87+
isolate,
88+
total,
89+
BackingStoreInitializationMode::kUninitialized,
90+
BackingStoreOnFailureMode::kReturnNull);
91+
if (!store) [[unlikely]] {
92+
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
93+
return;
94+
}
8795
uint8_t* ptr = static_cast<uint8_t*>(store->Data());
8896
for (size_t n = 0; n < views.size(); n++) {
8997
uint8_t* from =

src/node_buffer.cc

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ using v8::ArrayBuffer;
5959
using v8::ArrayBufferView;
6060
using v8::BackingStore;
6161
using v8::BackingStoreInitializationMode;
62+
using v8::BackingStoreOnFailureMode;
6263
using v8::CFunction;
6364
using v8::Context;
6465
using v8::EscapableHandleScope;
@@ -304,17 +305,20 @@ MaybeLocal<Object> New(Isolate* isolate,
304305
EscapableHandleScope scope(isolate);
305306

306307
size_t length;
307-
if (!StringBytes::Size(isolate, string, enc).To(&length))
308-
return Local<Object>();
308+
if (!StringBytes::Size(isolate, string, enc).To(&length)) return {};
309309
size_t actual = 0;
310310
std::unique_ptr<BackingStore> store;
311311

312312
if (length > 0) {
313-
store = ArrayBuffer::NewBackingStore(isolate, length);
313+
store = ArrayBuffer::NewBackingStore(
314+
isolate,
315+
length,
316+
BackingStoreInitializationMode::kZeroInitialized,
317+
BackingStoreOnFailureMode::kReturnNull);
314318

315319
if (!store) [[unlikely]] {
316320
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
317-
return Local<Object>();
321+
return {};
318322
}
319323

320324
actual = StringBytes::Write(
@@ -329,7 +333,14 @@ MaybeLocal<Object> New(Isolate* isolate,
329333
if (actual < length) {
330334
std::unique_ptr<BackingStore> old_store = std::move(store);
331335
store = ArrayBuffer::NewBackingStore(
332-
isolate, actual, BackingStoreInitializationMode::kUninitialized);
336+
isolate,
337+
actual,
338+
BackingStoreInitializationMode::kUninitialized,
339+
BackingStoreOnFailureMode::kReturnNull);
340+
if (!store) [[unlikely]] {
341+
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
342+
return {};
343+
}
333344
memcpy(store->Data(), old_store->Data(), actual);
334345
}
335346
Local<ArrayBuffer> buf = ArrayBuffer::New(isolate, std::move(store));
@@ -372,7 +383,14 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
372383
Local<ArrayBuffer> ab;
373384
{
374385
std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore(
375-
isolate, length, BackingStoreInitializationMode::kUninitialized);
386+
isolate,
387+
length,
388+
BackingStoreInitializationMode::kUninitialized,
389+
BackingStoreOnFailureMode::kReturnNull);
390+
if (!bs) [[unlikely]] {
391+
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
392+
return {};
393+
}
376394

377395
CHECK(bs);
378396

@@ -412,9 +430,14 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
412430
}
413431

414432
std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore(
415-
isolate, length, BackingStoreInitializationMode::kUninitialized);
416-
417-
CHECK(bs);
433+
isolate,
434+
length,
435+
BackingStoreInitializationMode::kUninitialized,
436+
BackingStoreOnFailureMode::kReturnNull);
437+
if (!bs) [[unlikely]] {
438+
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
439+
return {};
440+
}
418441

419442
if (length > 0) memcpy(bs->Data(), data, length);
420443

@@ -1449,8 +1472,8 @@ void CreateUnsafeArrayBuffer(const FunctionCallbackInfo<Value>& args) {
14491472
BackingStoreInitializationMode::kUninitialized,
14501473
v8::BackingStoreOnFailureMode::kReturnNull);
14511474

1452-
if (!store) {
1453-
env->ThrowRangeError("Array buffer allocation failed");
1475+
if (!store) [[unlikely]] {
1476+
THROW_ERR_MEMORY_ALLOCATION_FAILED(env);
14541477
return;
14551478
}
14561479

src/node_errors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details);
106106
V(ERR_INVALID_URL_PATTERN, TypeError) \
107107
V(ERR_INVALID_URL_SCHEME, TypeError) \
108108
V(ERR_LOAD_SQLITE_EXTENSION, Error) \
109-
V(ERR_MEMORY_ALLOCATION_FAILED, Error) \
109+
V(ERR_MEMORY_ALLOCATION_FAILED, RangeError) \
110110
V(ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE, Error) \
111111
V(ERR_MISSING_ARGS, TypeError) \
112112
V(ERR_MISSING_PASSPHRASE, TypeError) \

0 commit comments

Comments
 (0)