Skip to content

Commit 651a5b5

Browse files
trevnorrisjasnell
authored andcommitted
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 PR-URL: #3080 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent d5a1b1a commit 651a5b5

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

src/node_buffer.cc

+9-12
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,20 @@ void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
163163
// Buffer methods
164164

165165
boolHasInstance(Local<Value> val) {
166-
return val->IsObject() && HasInstance(val.As<Object>());
166+
return val->IsUint8Array();
167167
}
168168

169169

170170
boolHasInstance(Local<Object> obj) {
171-
if (!obj->IsUint8Array())
172-
returnfalse;
173-
Local<Uint8Array> array = obj.As<Uint8Array>();
174-
Environment* env = Environment::GetCurrent(array->GetIsolate());
175-
return array->GetPrototype()->StrictEquals(env->buffer_prototype_object());
171+
return obj->IsUint8Array();
176172
}
177173

178174

179175
char* Data(Local<Value> val) {
180-
CHECK(val->IsObject());
181-
// Use a fully qualified name here to work around a bug in gcc 4.2.
182-
// It mistakes an unadorned call to Data() for the v8::String::Data type.
183-
returnnode::Buffer::Data(val.As<Object>());
176+
CHECK(val->IsUint8Array());
177+
Local<Uint8Array> ui = val.As<Uint8Array>();
178+
ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents();
179+
returnstatic_cast<char*>(ab_c.Data()) + ui->ByteOffset();
184180
}
185181

186182

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

194190

195191
size_tLength(Local<Value> val) {
196-
CHECK(val->IsObject());
197-
returnLength(val.As<Object>());
192+
CHECK(val->IsUint8Array());
193+
Local<Uint8Array> ui = val.As<Uint8Array>();
194+
return ui->ByteLength();
198195
}
199196

200197

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=require('assert');
5+
6+
7+
functionT(n){
8+
constui8=newUint8Array(n);
9+
Object.setPrototypeOf(ui8,T.prototype);
10+
returnui8;
11+
}
12+
Object.setPrototypeOf(T.prototype,Buffer.prototype);
13+
Object.setPrototypeOf(T,Buffer);
14+
15+
T.prototype.sum=functionsum(){
16+
letcntr=0;
17+
for(leti=0;i<this.length;i++)
18+
cntr+=this[i];
19+
returncntr;
20+
};
21+
22+
23+
constvals=[newT(4),T(4)];
24+
25+
vals.forEach(function(t){
26+
assert.equal(t.constructor,T);
27+
assert.equal(t.__proto__,T.prototype);
28+
assert.equal(t.__proto__.__proto__,Buffer.prototype);
29+
30+
t.fill(5);
31+
letcntr=0;
32+
for(leti=0;i<t.length;i++)
33+
cntr+=t[i];
34+
assert.equal(t.length*5,cntr);
35+
36+
// Check this does not throw
37+
t.toString();
38+
});

0 commit comments

Comments
 (0)
close