@@ -77,7 +77,6 @@ using v8::Object;
7777using v8::SharedArrayBuffer;
7878using v8::String;
7979using v8::Uint32;
80- using v8::Uint32Array;
8180using v8::Uint8Array;
8281using v8::Value;
8382
@@ -1229,37 +1228,6 @@ void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
12291228 realm->set_buffer_prototype_object (proto);
12301229}
12311230
1232- void GetZeroFillToggle (const FunctionCallbackInfo<Value>& args) {
1233- Environment* env = Environment::GetCurrent (args);
1234- NodeArrayBufferAllocator* allocator = env->isolate_data ()->node_allocator ();
1235- Local<ArrayBuffer> ab;
1236- // It can be a nullptr when running inside an isolate where we
1237- // do not own the ArrayBuffer allocator.
1238- if (allocator == nullptr ) {
1239- // Create a dummy Uint32Array - the JS land can only toggle the C++ land
1240- // setting when the allocator uses our toggle. With this the toggle in JS
1241- // land results in no-ops.
1242- ab = ArrayBuffer::New (env->isolate (), sizeof (uint32_t ));
1243- } else {
1244- uint32_t * zero_fill_field = allocator->zero_fill_field ();
1245- std::unique_ptr<BackingStore> backing =
1246- ArrayBuffer::NewBackingStore (zero_fill_field,
1247- sizeof (*zero_fill_field),
1248- [](void *, size_t , void *) {},
1249- nullptr );
1250- ab = ArrayBuffer::New (env->isolate (), std::move (backing));
1251- }
1252-
1253- if (ab->SetPrivate (env->context (),
1254- env->untransferable_object_private_symbol (),
1255- True (env->isolate ()))
1256- .IsNothing ()) {
1257- return ;
1258- }
1259-
1260- args.GetReturnValue ().Set (Uint32Array::New (ab, 0 , 1 ));
1261- }
1262-
12631231static void Btoa (const FunctionCallbackInfo<Value>& args) {
12641232 CHECK_EQ (args.Length (), 1 );
12651233 Environment* env = Environment::GetCurrent (args);
@@ -1433,6 +1401,52 @@ void CopyArrayBuffer(const FunctionCallbackInfo<Value>& args) {
14331401 memcpy (dest, src, bytes_to_copy);
14341402}
14351403
1404+ // Converts a number parameter to size_t suitable for ArrayBuffer sizes
1405+ // Could be larger than uint32_t
1406+ // See v8::internal::TryNumberToSize and v8::internal::NumberToSize
1407+ inline size_t CheckNumberToSize (Local<Value> number) {
1408+ CHECK (number->IsNumber ());
1409+ double value = number.As <Number>()->Value ();
1410+ // See v8::internal::TryNumberToSize on this (and on < comparison)
1411+ double maxSize = static_cast <double >(std::numeric_limits<size_t >::max ());
1412+ CHECK (value >= 0 && value < maxSize);
1413+ size_t size = static_cast <size_t >(value);
1414+ #ifdef V8_ENABLE_SANDBOX
1415+ CHECK_LE (size, kMaxSafeBufferSizeForSandbox );
1416+ #endif
1417+ return size;
1418+ }
1419+
1420+ void CreateUnsafeArrayBuffer (const FunctionCallbackInfo<Value>& args) {
1421+ Environment* env = Environment::GetCurrent (args);
1422+ if (args.Length () != 1 ) {
1423+ env->ThrowRangeError (" Invalid array buffer length" );
1424+ return ;
1425+ }
1426+
1427+ size_t size = CheckNumberToSize (args[0 ]);
1428+
1429+ Isolate* isolate = env->isolate ();
1430+
1431+ Local<ArrayBuffer> buf;
1432+
1433+ NodeArrayBufferAllocator* allocator = env->isolate_data ()->node_allocator ();
1434+ // 0-length, or zero-fill flag is set, or building snapshot
1435+ if (size == 0 || per_process::cli_options->zero_fill_all_buffers ||
1436+ allocator == nullptr ) {
1437+ buf = ArrayBuffer::New (isolate, size);
1438+ } else {
1439+ std::unique_ptr<BackingStore> store =
1440+ ArrayBuffer::NewBackingStoreForNodeLTS (isolate, size);
1441+ if (!store) {
1442+ return env->ThrowRangeError (" Array buffer allocation failed" );
1443+ }
1444+ buf = ArrayBuffer::New (isolate, std::move (store));
1445+ }
1446+
1447+ args.GetReturnValue ().Set (buf);
1448+ }
1449+
14361450template <encoding encoding>
14371451uint32_t WriteOneByteString (const char * src,
14381452 uint32_t src_len,
@@ -1550,6 +1564,8 @@ void Initialize(Local<Object> target,
15501564 SetMethodNoSideEffect (context, target, " indexOfString" , IndexOfString);
15511565
15521566 SetMethod (context, target, " copyArrayBuffer" , CopyArrayBuffer);
1567+ SetMethodNoSideEffect (
1568+ context, target, " createUnsafeArrayBuffer" , CreateUnsafeArrayBuffer);
15531569
15541570 SetMethod (context, target, " swap16" , Swap16);
15551571 SetMethod (context, target, " swap32" , Swap32);
@@ -1599,8 +1615,6 @@ void Initialize(Local<Object> target,
15991615 " utf8WriteStatic" ,
16001616 SlowWriteString<UTF8>,
16011617 &fast_write_string_utf8);
1602-
1603- SetMethod (context, target, " getZeroFillToggle" , GetZeroFillToggle);
16041618}
16051619
16061620} // anonymous namespace
@@ -1649,9 +1663,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
16491663 registry->Register (StringWrite<HEX>);
16501664 registry->Register (StringWrite<UCS2>);
16511665 registry->Register (StringWrite<UTF8>);
1652- registry->Register (GetZeroFillToggle);
16531666
16541667 registry->Register (CopyArrayBuffer);
1668+ registry->Register (CreateUnsafeArrayBuffer);
16551669
16561670 registry->Register (Atob);
16571671 registry->Register (Btoa);
0 commit comments