3232#include " simdutf.h"
3333#include " string_bytes.h"
3434
35+ #include " node_v8_sandbox.h"
3536#include " util-inl.h"
3637#include " v8-fast-api-calls.h"
3738#include " v8.h"
@@ -123,6 +124,18 @@ Local<ArrayBuffer> CallbackInfo::CreateTrackedArrayBuffer(
123124 CHECK_NOT_NULL (callback);
124125 CHECK_IMPLIES (data == nullptr , length == 0 );
125126
127+ #ifdef V8_ENABLE_SANDBOX
128+ // When the V8 sandbox is enabled, external backing stores are not supported.
129+ // Copy the data into the cage and immediately free the original via callback.
130+ void * cage_data = SandboxAllocate (length, /* zero_fill */ false );
131+ CHECK_NOT_NULL (cage_data);
132+ if (length > 0 ) memcpy (cage_data, data, length);
133+ callback (data, hint);
134+ std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore (
135+ cage_data, length, SandboxBackingStoreDeleter, nullptr );
136+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), std::move (bs));
137+ // No CallbackInfo needed — the original data has already been freed.
138+ #else
126139 CallbackInfo* self = new CallbackInfo (env, callback, data, hint);
127140 std::unique_ptr<BackingStore> bs =
128141 ArrayBuffer::NewBackingStore (data, length, [](void *, size_t , void * arg) {
@@ -140,6 +153,7 @@ Local<ArrayBuffer> CallbackInfo::CreateTrackedArrayBuffer(
140153 self->persistent_ .Reset (env->isolate (), ab);
141154 self->persistent_ .SetWeak ();
142155 }
156+ #endif // V8_ENABLE_SANDBOX
143157
144158 return ab;
145159}
@@ -1452,9 +1466,7 @@ inline size_t CheckNumberToSize(Local<Value> number) {
14521466 double maxSize = static_cast <double >(std::numeric_limits<size_t >::max ());
14531467 CHECK (value >= 0 && value < maxSize);
14541468 size_t size = static_cast <size_t >(value);
1455- #ifdef V8_ENABLE_SANDBOX
1456- CHECK_LE (size, v8::internal::kMaxSafeBufferSizeForSandbox );
1457- #endif
1469+ CHECK_LE (size, v8::ArrayBuffer::kMaxByteLength );
14581470 return size;
14591471}
14601472
@@ -1476,35 +1488,13 @@ void CreateUnsafeArrayBuffer(const FunctionCallbackInfo<Value>& args) {
14761488 env->isolate_data ()->is_building_snapshot ()) {
14771489 buf = ArrayBuffer::New (isolate, size);
14781490 } else {
1479- #ifdef V8_ENABLE_SANDBOX
1480- std::unique_ptr<ArrayBuffer::Allocator> allocator (
1481- ArrayBuffer::Allocator::NewDefaultAllocator ());
1482- void * data = allocator->AllocateUninitialized (size);
1491+ void * data = SandboxAllocate (size, /* zero_fill */ false );
14831492 if (!data) [[unlikely]] {
14841493 THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
14851494 return ;
14861495 }
14871496 std::unique_ptr<BackingStore> store = ArrayBuffer::NewBackingStore (
1488- data,
1489- size,
1490- [](void * data, size_t length, void *) {
1491- std::unique_ptr<ArrayBuffer::Allocator> allocator (
1492- ArrayBuffer::Allocator::NewDefaultAllocator ());
1493- allocator->Free (data, length);
1494- },
1495- nullptr );
1496- #else
1497- std::unique_ptr<BackingStore> store = ArrayBuffer::NewBackingStore (
1498- isolate,
1499- size,
1500- BackingStoreInitializationMode::kUninitialized ,
1501- v8::BackingStoreOnFailureMode::kReturnNull );
1502-
1503- if (!store) [[unlikely]] {
1504- THROW_ERR_MEMORY_ALLOCATION_FAILED (env);
1505- return ;
1506- }
1507- #endif
1497+ data, size, SandboxBackingStoreDeleter, nullptr );
15081498
15091499 buf = ArrayBuffer::New (isolate, std::move (store));
15101500 }
0 commit comments