buffer: fix assertion error in WeakCallback
authorFedor Indutny <fedor@indutny.com>
Mon, 12 Oct 2015 20:08:13 +0000 (16:08 -0400)
committerJames M Snell <jasnell@gmail.com>
Tue, 13 Oct 2015 03:57:12 +0000 (20:57 -0700)
`CallbackInfo` is now bound to `ArrayBuffer` instance, not `Uint8Array`,
therefore `SPREAD_ARG` will abort with:

    Assertion failed: ((object)->IsUint8Array())

Make changes necessary to migrate it to `ArrayBuffer`.

See: https://github.com/nodejs/node/pull/3080#issuecomment-147502167

Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/3329

src/node_buffer.cc
test/addons/buffer-free-callback/binding.cc
test/addons/buffer-free-callback/test.js

index 4df7a9f..a472d0c 100644 (file)
@@ -148,11 +148,14 @@ void CallbackInfo::WeakCallback(
 
 
 void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
-  SPREAD_ARG(object, obj);
-  CHECK_EQ(obj_offset, 0);
-  CHECK_EQ(obj_c.ByteLength(), obj_length);
-
-  obj->Buffer()->Neuter();
+  CHECK(object->IsArrayBuffer());
+  Local<ArrayBuffer> buf = object.As<ArrayBuffer>();
+  ArrayBuffer::Contents obj_c = buf->GetContents();
+  char* const obj_data = static_cast<char*>(obj_c.Data());
+  if (buf->ByteLength() != 0)
+    CHECK_NE(obj_data, nullptr);
+
+  buf->Neuter();
   callback_(obj_data, hint_);
   int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this));
   isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
index a1e7773..e5298a0 100644 (file)
@@ -16,7 +16,7 @@ void Alloc(const v8::FunctionCallbackInfo<v8::Value>& args) {
   args.GetReturnValue().Set(node::Buffer::New(
         isolate,
         buf,
-        sizeof(buf),
+        args[0]->IntegerValue(),
         FreeCallback,
         nullptr).ToLocalChecked());
 }
index b95f171..6ee328d 100644 (file)
@@ -4,7 +4,20 @@
 require('../../common');
 var assert = require('assert');
 var binding = require('./build/Release/binding');
-var buf = binding.alloc();
-var slice = buf.slice(32);
-buf = null;
-binding.check(slice);
+
+function check(size) {
+  var buf = binding.alloc(size);
+  var slice = buf.slice(size >>> 1);
+
+  buf = null;
+  binding.check(slice);
+  slice = null;
+  gc();
+  gc();
+  gc();
+}
+
+check(64);
+
+// Empty ArrayBuffer does not allocate data, worth checking
+check(0);