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: https://github.com/nodejs/node/issues/2882 PR-URL: https://github.com/nodejs/node/pull/3080 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
8a685e7fe3
commit
05d424c029
@ -163,24 +163,20 @@ void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
|
|||||||
// Buffer methods
|
// Buffer methods
|
||||||
|
|
||||||
bool HasInstance(Local<Value> val) {
|
bool HasInstance(Local<Value> val) {
|
||||||
return val->IsObject() && HasInstance(val.As<Object>());
|
return val->IsUint8Array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HasInstance(Local<Object> obj) {
|
bool HasInstance(Local<Object> obj) {
|
||||||
if (!obj->IsUint8Array())
|
return obj->IsUint8Array();
|
||||||
return false;
|
|
||||||
Local<Uint8Array> array = obj.As<Uint8Array>();
|
|
||||||
Environment* env = Environment::GetCurrent(array->GetIsolate());
|
|
||||||
return array->GetPrototype()->StrictEquals(env->buffer_prototype_object());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char* Data(Local<Value> val) {
|
char* Data(Local<Value> val) {
|
||||||
CHECK(val->IsObject());
|
CHECK(val->IsUint8Array());
|
||||||
// Use a fully qualified name here to work around a bug in gcc 4.2.
|
Local<Uint8Array> ui = val.As<Uint8Array>();
|
||||||
// It mistakes an unadorned call to Data() for the v8::String::Data type.
|
ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents();
|
||||||
return node::Buffer::Data(val.As<Object>());
|
return static_cast<char*>(ab_c.Data()) + ui->ByteOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -193,8 +189,9 @@ char* Data(Local<Object> obj) {
|
|||||||
|
|
||||||
|
|
||||||
size_t Length(Local<Value> val) {
|
size_t Length(Local<Value> val) {
|
||||||
CHECK(val->IsObject());
|
CHECK(val->IsUint8Array());
|
||||||
return Length(val.As<Object>());
|
Local<Uint8Array> ui = val.As<Uint8Array>();
|
||||||
|
return ui->ByteLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
38
test/parallel/test-buffer-inheritance.js
Normal file
38
test/parallel/test-buffer-inheritance.js
Normal file
@ -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();
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user