Browse Source

buffer: fix assertion error in WeakCallback

`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
v4.x
Fedor Indutny 9 years ago
committed by James M Snell
parent
commit
b3cbd13340
  1. 13
      src/node_buffer.cc
  2. 2
      test/addons/buffer-free-callback/binding.cc
  3. 21
      test/addons/buffer-free-callback/test.js

13
src/node_buffer.cc

@ -148,11 +148,14 @@ void CallbackInfo::WeakCallback(
void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) { void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
SPREAD_ARG(object, obj); CHECK(object->IsArrayBuffer());
CHECK_EQ(obj_offset, 0); Local<ArrayBuffer> buf = object.As<ArrayBuffer>();
CHECK_EQ(obj_c.ByteLength(), obj_length); ArrayBuffer::Contents obj_c = buf->GetContents();
char* const obj_data = static_cast<char*>(obj_c.Data());
obj->Buffer()->Neuter(); if (buf->ByteLength() != 0)
CHECK_NE(obj_data, nullptr);
buf->Neuter();
callback_(obj_data, hint_); callback_(obj_data, hint_);
int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this)); int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this));
isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes); isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);

2
test/addons/buffer-free-callback/binding.cc

@ -16,7 +16,7 @@ void Alloc(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(node::Buffer::New( args.GetReturnValue().Set(node::Buffer::New(
isolate, isolate,
buf, buf,
sizeof(buf), args[0]->IntegerValue(),
FreeCallback, FreeCallback,
nullptr).ToLocalChecked()); nullptr).ToLocalChecked());
} }

21
test/addons/buffer-free-callback/test.js

@ -4,7 +4,20 @@
require('../../common'); require('../../common');
var assert = require('assert'); var assert = require('assert');
var binding = require('./build/Release/binding'); var binding = require('./build/Release/binding');
var buf = binding.alloc();
var slice = buf.slice(32); function check(size) {
buf = null; var buf = binding.alloc(size);
binding.check(slice); 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);

Loading…
Cancel
Save