Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
buffer: Only check if instance is Uint8Array
Native Buffer method calls do not require anything from the prototype.
So it is unnecessary to check if the Object's prototype is equal to
Buffer.prototype.

This fixes an issue that prevents Buffer from being inherited the ES5
way. Now the following will work:

    function A(n) {
      const b = new Buffer(n);
      Object.setPrototypeOf(b, A.prototype);
      return b;
    }

    Object.setPrototypeOf(A.prototype, Buffer.prototype);
    Object.setPrototypeOf(A, Buffer);

    console.log(new A(4));

Fix: #2882
  • Loading branch information
trevnorris committed Oct 6, 2015
commit b7eb4f1acff7f01efd1f0a5a1c7ad1a2ea6c2631
21 changes: 9 additions & 12 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,20 @@ void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
// Buffer methods

bool HasInstance(Local<Value> val) {
return val->IsObject() && HasInstance(val.As<Object>());
return val->IsUint8Array();
}


bool HasInstance(Local<Object> obj) {
if (!obj->IsUint8Array())
return false;
Local<Uint8Array> array = obj.As<Uint8Array>();
Environment* env = Environment::GetCurrent(array->GetIsolate());
return array->GetPrototype()->StrictEquals(env->buffer_prototype_object());
return obj->IsUint8Array();
}


char* Data(Local<Value> val) {
CHECK(val->IsObject());
// Use a fully qualified name here to work around a bug in gcc 4.2.
// It mistakes an unadorned call to Data() for the v8::String::Data type.
return node::Buffer::Data(val.As<Object>());
CHECK(val->IsUint8Array());
Local<Uint8Array> ui = val.As<Uint8Array>();
ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents();
return static_cast<char*>(ab_c.Data()) + ui->ByteOffset();
}


Expand All @@ -193,8 +189,9 @@ char* Data(Local<Object> obj) {


size_t Length(Local<Value> val) {
CHECK(val->IsObject());
return Length(val.As<Object>());
CHECK(val->IsUint8Array());
Local<Uint8Array> ui = val.As<Uint8Array>();
return ui->ByteLength();
}


Expand Down
38 changes: 38 additions & 0 deletions test/parallel/test-buffer-inheritance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const common = require('../common');
const assert = require('assert');


function T(n) {
const ui8 = new Uint8Array(n);
Object.setPrototypeOf(ui8, T.prototype);
return ui8;
}
Object.setPrototypeOf(T.prototype, Buffer.prototype);
Object.setPrototypeOf(T, Buffer);

T.prototype.sum = function sum() {
let cntr = 0;
for (let i = 0; i < this.length; i++)
cntr += this[i];
return cntr;
};


const vals = [new T(4), T(4)];

vals.forEach(function(t) {
assert.equal(t.constructor, T);
assert.equal(t.__proto__, T.prototype);
assert.equal(t.__proto__.__proto__, Buffer.prototype);

t.fill(5);
let cntr = 0;
for (let i = 0; i < t.length; i++)
cntr += t[i];
assert.equal(t.length * 5, cntr);

// Check this does not throw
t.toString();
});