test: fix test for buffer regression #649 by joyeecheung · Pull Request #9924 · nodejs/node

I dug around a little bit and found out why Buffer.allocUnsafe(0x10000000000000000) return a empty buffer:

* thread #1: tid = 0x15c9bc, 0x0000000100464fe5 node`v8::internal::Builtin_Impl_ArrayBufferConstructor_ConstructStub(args=BuiltinArguments @ 0x00007fff5fbfdcf8, isolate=0x0000000106000000) + 1317 at builtins-arraybuffer.cc:52, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
  * frame #0: 0x0000000100464fe5 node`v8::internal::Builtin_Impl_ArrayBufferConstructor_ConstructStub(args=BuiltinArguments @ 0x00007fff5fbfdcf8, isolate=0x0000000106000000) + 1317 at builtins-arraybuffer.cc:52
    frame #1: 0x00000001004649ff node`v8::internal::Builtin_ArrayBufferConstructor_ConstructStub(args_length=5, args_object=0x00007fff5fbfddd0, isolate=0x0000000106000000) + 255 at builtins-arraybuffer.cc:26
    frame #3: 0x00000e1102909ec7 createUnsafeArrayBuffer(this=0x00002a4274304311:<undefined>, 0x000018207b7673b1:<Number: 18446744073709551616.000000>) at buffer.js:40:33 fn=0x00001e06fe02c9f9
    frame #4: 0x00000e1102953ce6 createUnsafeBuffer(this=0x00002a4274304311:<undefined>, 0x000018207b7673b1:<Number: 18446744073709551616.000000>) at buffer.js:36:28 fn=0x00001e06fe08ce91
    frame #5: 0x00000e110293cfb6 allocate(this=0x00002a4274304311:<undefined>, 0x000018207b7673b1:<Number: 18446744073709551616.000000>) at buffer.js:177:18 fn=0x00001e06fe06e741
    frame #11: 0x00000e11029376e1 tryModuleLoad(this=0x00002a4274304311:<undefined>, 0x00001e06fe012021:<Object: Module>, 0x00001e06fe0121e9:<String: "/Users/joyee/pro...">) at module.js:444:23 fn=0x00001e06fe0124d9
    frame #15: 0x00000e110287a96b startup(this=0x00002a4274304311:<undefined>) at bootstrap_node.js:1:10 fn=0x00001e06fe012679
    frame #17: 0x00000e110284aa83 <internal>
    frame #18: 0x00000e110282ac41 <entry>
    frame #19: 0x0000000100afe75e node`v8::internal::(anonymous namespace)::Invoke(isolate=0x0000000106000000, is_construct=false, target=Handle<v8::internal::Object> @ 0x00007fff5fbfe4d0, receiver=Handle<v8::internal::Object> @ 0x00007fff5fbfe4c8, argc=1, args=0x00007fff5fbfe818, new_target=Handle<v8::internal::Object> @ 0x00007fff5fbfe4c0) + 1470 at execution.cc:141
    frame #20: 0x0000000100afe118 node`v8::internal::Execution::Call(isolate=0x0000000106000000, callable=Handle<v8::internal::Object> @ 0x00007fff5fbfe588, receiver=Handle<v8::internal::Object> @ 0x00007fff5fbfe580, argc=1, argv=0x00007fff5fbfe818) + 280 at execution.cc:178
    frame #21: 0x000000010034c8e5 node`v8::Function::Call(this=0x0000000106051d98, context=(val_ = 0x0000000106051de0), recv=(val_ = 0x0000000106000078), argc=1, argv=0x00007fff5fbfe818) + 773 at api.cc:4521
    frame #22: 0x000000010034ca61 node`v8::Function::Call(this=0x0000000106051d98, recv=(val_ = 0x0000000106000078), argc=1, argv=0x00007fff5fbfe818) + 113 at api.cc:4530
    frame #23: 0x000000010003182f node`node::LoadEnvironment(env=0x00007fff5fbfe9c8) + 703 at node.cc:3469
    frame #24: 0x0000000100037336 node`node::Start(isolate=0x0000000106000000, isolate_data=0x00007fff5fbff368, argc=2, argv=0x0000000103d00120, exec_argc=0, exec_argv=0x0000000103d00000) + 486 at node.cc:4432
    frame #25: 0x0000000100033e6c node`node::Start(event_loop=0x00000001021ebf90, argc=2, argv=0x0000000103d00120, exec_argc=0, exec_argv=0x0000000103d00000) + 524 at node.cc:4509
    frame #26: 0x0000000100033874 node`node::Start(argc=2, argv=0x0000000103d00120) + 388 at node.cc:4555
    frame #27: 0x000000010007cb3e node`main(argc=2, argv=0x00007fff5fbff828) + 94 at node_main.cc:58
    frame #28: 0x0000000100001534 node`start + 52

Here ArrayBufferConstructor_ConstructStub gets a 0 as byte_length because there is a cast error triggered by floating number precision problems in TryNumberToSize:

// // 1.8446744073709552E+19, that is, 0x10000000000000000 with possibly some floating number inaccuracy
double value = HeapNumber::cast(number)->value();  
// on my machine the limit is 18446744073709551615, just a bit less than 18446744073709552000 = 0x10000000000000000
if (value >= 0 && value <= std::numeric_limits<size_t>::max()) {  
  *result = static_cast<size_t>(value);  // 0
  return true;
} else {
  return false;
}

If you add one more 0 to the number, then you will hit the std::numeric_limits<size_t>::max() here and return false, then get a Invalid array buffer length thrown by this stub.