Skip to content

Commit b7ddd2a

Browse files
ChALkeRljharb
authored andcommitted
[Fix] io.js 3.0 - Node.js 5.3 typed array support
1 parent f03cebf commit b7ddd2a

File tree

2 files changed

+120
-29
lines changed

2 files changed

+120
-29
lines changed

index.js

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,42 +28,67 @@ var useArrayBuffer = typeof ArrayBuffer !== 'undefined'
2828
&& ArrayBuffer.isView
2929
&& (Buffer.prototype instanceof Uint8Array || Buffer.TYPED_ARRAY_SUPPORT);
3030

31-
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
32-
var bufferData;
31+
function toBuffer(data, encoding) {
32+
/*
33+
* No need to do anything for exact instance
34+
* This is only valid when safe-buffer.Buffer === buffer.Buffer, i.e. when Buffer.from/Buffer.alloc existed
35+
*/
3336
if (data instanceof Buffer) {
34-
// No need to do anything
35-
bufferData = data;
36-
} else if (typeof data === 'string') {
37-
// Convert strings to Buffer
38-
bufferData = Buffer.from(data, inputEnc);
39-
} else if (useArrayBuffer && ArrayBuffer.isView(data)) {
40-
/*
41-
* Wrap any TypedArray instances and DataViews
42-
* Makes sense only on engines with full TypedArray support -- let Buffer detect that
43-
*/
44-
bufferData = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
45-
} else if (useUint8Array && data instanceof Uint8Array) {
37+
return data;
38+
}
39+
40+
// Convert strings to Buffer
41+
if (typeof data === 'string') {
42+
return Buffer.from(data, encoding);
43+
}
44+
45+
/*
46+
* Wrap any TypedArray instances and DataViews
47+
* Makes sense only on engines with full TypedArray support -- let Buffer detect that
48+
*/
49+
if (useArrayBuffer && ArrayBuffer.isView(data)) {
50+
// Bug in Node.js <6.3.1, which treats this as out-of-bounds
51+
if (data.byteLength === 0) {
52+
return Buffer.alloc(0);
53+
}
54+
55+
var res = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
4656
/*
47-
* Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over
48-
* Doesn't make sense with other TypedArray instances
57+
* Recheck result size, as offset/length doesn't work on Node.js <5.10
58+
* We just go to Uint8Array case if this fails
4959
*/
50-
bufferData = Buffer.from(data);
51-
} else if (
60+
if (res.byteLength === data.byteLength) {
61+
return res;
62+
}
63+
}
64+
65+
/*
66+
* Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over
67+
* Doesn't make sense with other TypedArray instances
68+
*/
69+
if (useUint8Array && data instanceof Uint8Array) {
70+
return Buffer.from(data);
71+
}
72+
73+
/*
74+
* Old Buffer polyfill on an engine that doesn't have TypedArray support
75+
* Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed
76+
* Convert to our current Buffer implementation
77+
*/
78+
if (
5279
Buffer.isBuffer(data)
53-
&& data.constructor
54-
&& data.constructor.isBuffer
55-
&& data.constructor.isBuffer(data)
80+
&& data.constructor
81+
&& typeof data.constructor.isBuffer === 'function'
82+
&& data.constructor.isBuffer(data)
5683
) {
57-
/*
58-
* Old Buffer polyfill on an engine that doesn't have TypedArray support
59-
* Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed
60-
* Convert to our current Buffer implementation
61-
*/
62-
bufferData = Buffer.from(data);
63-
} else {
64-
throw new Error('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.');
84+
return Buffer.from(data);
6585
}
6686

87+
throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.');
88+
}
89+
90+
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
91+
var bufferData = toBuffer(data, inputEnc); // asserts correct input type
6792
var outData = this._update(bufferData);
6893
if (this.hashMode) {
6994
return this;

test/index.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,72 @@ test('encodings', function (t) {
129129
});
130130
});
131131

132+
test('handle SafeBuffer instances', function (t) {
133+
function Cipher() {
134+
CipherBase.call(this, 'finalName');
135+
this._cache = [];
136+
}
137+
inherits(Cipher, CipherBase);
138+
Cipher.prototype._update = function (input) {
139+
t.ok(Buffer.isBuffer(input));
140+
this._cache.push(input);
141+
};
142+
Cipher.prototype._final = function () {
143+
return Buffer.concat(this._cache);
144+
};
145+
146+
var cipher = new Cipher();
147+
var final = cipher.update(Buffer.from('a0c1', 'hex')).finalName('hex');
148+
t.equals(final, 'a0c1');
149+
150+
t.end();
151+
});
152+
153+
test('handle Uint8Array view', function (t) {
154+
function Cipher() {
155+
CipherBase.call(this, 'finalName');
156+
this._cache = [];
157+
}
158+
inherits(Cipher, CipherBase);
159+
Cipher.prototype._update = function (input) {
160+
t.ok(Buffer.isBuffer(input));
161+
this._cache.push(input);
162+
};
163+
Cipher.prototype._final = function () {
164+
return Buffer.concat(this._cache);
165+
};
166+
167+
var buf = new Uint8Array([0, 1, 2, 3, 4, 5]);
168+
var uarr = new Uint8Array(buf.buffer, 2, 3);
169+
170+
var cipher = new Cipher();
171+
var final = cipher.update(uarr).finalName('hex');
172+
t.equals(final, '020304');
173+
174+
t.end();
175+
});
176+
177+
test('handle empty Uint8Array instances', function (t) {
178+
function Cipher() {
179+
CipherBase.call(this, 'finalName');
180+
this._cache = [];
181+
}
182+
inherits(Cipher, CipherBase);
183+
Cipher.prototype._update = function (input) {
184+
t.ok(Buffer.isBuffer(input));
185+
this._cache.push(input);
186+
};
187+
Cipher.prototype._final = function () {
188+
return Buffer.concat(this._cache);
189+
};
190+
191+
var cipher = new Cipher();
192+
var final = cipher.update(new Uint8Array(0)).finalName('hex');
193+
t.equals(final, '');
194+
195+
t.end();
196+
});
197+
132198
test('handle UInt16Array', function (t) {
133199
function Cipher() {
134200
CipherBase.call(this, 'finalName');

0 commit comments

Comments
 (0)