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 <[email protected]>
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
bool HasInstance(Local<Value> val) {
166-
return val->IsObject() && HasInstance(val.As<Object>());
166+
return val->IsUint8Array();
167167
}
168168

169169

170170
bool HasInstance(Local<Object> obj) {
171-
if (!obj->IsUint8Array())
172-
return false;
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-
return node::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+
return static_cast<char*>(ab_c.Data()) + ui->ByteOffset();
184180
}
185181

186182

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

194190

195191
size_t Length(Local<Value> val) {
196-
CHECK(val->IsObject());
197-
return Length(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+
const common = require('../common');
4+
const assert = require('assert');
5+
6+
7+
function T(n) {
8+
const ui8 = new Uint8Array(n);
9+
Object.setPrototypeOf(ui8, T.prototype);
10+
return ui8;
11+
}
12+
Object.setPrototypeOf(T.prototype, Buffer.prototype);
13+
Object.setPrototypeOf(T, Buffer);
14+
15+
T.prototype.sum = function sum() {
16+
let cntr = 0;
17+
for (let i = 0; i < this.length; i++)
18+
cntr += this[i];
19+
return cntr;
20+
};
21+
22+
23+
const vals = [new T(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+
let cntr = 0;
32+
for (let i = 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)