22'use strict';
33
44const binding = process.binding('buffer');
5+ const { isArrayBuffer } = process.binding('util');
56const bindingObj = {};
67
8+ class FastBuffer extends Uint8Array {}
9+
10+ FastBuffer.prototype.constructor = Buffer;
11+ Buffer.prototype = FastBuffer.prototype;
12+
713exports.Buffer = Buffer;
814exports.SlowBuffer = SlowBuffer;
915exports.INSPECT_MAX_BYTES = 50;
@@ -62,20 +68,18 @@ Buffer.prototype.swap32 = function swap32() {
6268const flags = bindingObj.flags;
6369const kNoZeroFill = 0;
6470
65- function createBuffer (size, noZeroFill ) {
66- flags[kNoZeroFill] = noZeroFill ? 1 : 0 ;
71+ function createUnsafeBuffer (size) {
72+ flags[kNoZeroFill] = 1 ;
6773 try {
68- const ui8 = new Uint8Array(size);
69- Object.setPrototypeOf(ui8, Buffer.prototype);
70- return ui8;
74+ return new FastBuffer(size);
7175 } finally {
7276 flags[kNoZeroFill] = 0;
7377 }
7478}
7579
7680function createPool() {
7781 poolSize = Buffer.poolSize;
78- allocPool = createBuffer (poolSize, true );
82+ allocPool = createUnsafeBuffer (poolSize);
7983 poolOffset = 0;
8084}
8185createPool();
@@ -133,7 +137,6 @@ Buffer.from = function(value, encodingOrOffset, length) {
133137 return fromObject(value);
134138};
135139
136- Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
137140Object.setPrototypeOf(Buffer, Uint8Array);
138141
139142function assertSize(size) {
@@ -153,18 +156,16 @@ function assertSize(size) {
153156 **/
154157Buffer.alloc = function(size, fill, encoding) {
155158 assertSize(size);
156- if (size <= 0)
157- return createBuffer(size);
158- if (fill !== undefined) {
159+ if (size > 0 && fill !== undefined) {
159160 // Since we are filling anyway, don't zero fill initially.
160161 // Only pay attention to encoding if it's a string. This
161162 // prevents accidentally sending in a number that would
162163 // be interpretted as a start offset.
163- return typeof encoding === 'string' ?
164- createBuffer(size, true).fill(fill, encoding) :
165- createBuffer (size, true ).fill(fill);
164+ if ( typeof encoding !== 'string')
165+ encoding = undefined;
166+ return createUnsafeBuffer (size).fill(fill, encoding );
166167 }
167- return createBuffer (size);
168+ return new FastBuffer (size);
168169};
169170
170171/**
@@ -183,15 +184,15 @@ Buffer.allocUnsafe = function(size) {
183184 **/
184185Buffer.allocUnsafeSlow = function(size) {
185186 assertSize(size);
186- return createBuffer (size, true );
187+ return createUnsafeBuffer (size);
187188};
188189
189190// If --zero-fill-buffers command line argument is set, a zero-filled
190191// buffer is returned.
191192function SlowBuffer(length) {
192193 if (+length != length)
193194 length = 0;
194- return createBuffer (+length, true );
195+ return createUnsafeBuffer (+length);
195196}
196197
197198Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype);
@@ -200,7 +201,7 @@ Object.setPrototypeOf(SlowBuffer, Uint8Array);
200201
201202function allocate(size) {
202203 if (size <= 0) {
203- return createBuffer(0 );
204+ return new FastBuffer( );
204205 }
205206 if (size < (Buffer.poolSize >>> 1)) {
206207 if (size > (poolSize - poolOffset))
@@ -213,7 +214,7 @@ function allocate(size) {
213214 // Even though this is checked above, the conditional is a safety net and
214215 // sanity check to prevent any subsequent typed array allocation from not
215216 // being zero filled.
216- return createBuffer (size, true );
217+ return createUnsafeBuffer (size);
217218 }
218219}
219220
@@ -226,7 +227,7 @@ function fromString(string, encoding) {
226227 throw new TypeError('"encoding" must be a valid string encoding');
227228
228229 if (string.length === 0)
229- return Buffer.alloc(0 );
230+ return new FastBuffer( );
230231
231232 var length = byteLength(string, encoding);
232233
@@ -246,18 +247,30 @@ function fromArrayLike(obj) {
246247 const length = obj.length;
247248 const b = allocate(length);
248249 for (var i = 0; i < length; i++)
249- b[i] = obj[i] & 255 ;
250+ b[i] = obj[i];
250251 return b;
251252}
252253
253254function fromArrayBuffer(obj, byteOffset, length) {
255+ if (!isArrayBuffer(obj))
256+ throw new TypeError('argument is not an ArrayBuffer');
257+
254258 byteOffset >>>= 0;
255259
256- if (typeof length === 'undefined')
257- return binding.createFromArrayBuffer(obj, byteOffset);
260+ const maxLength = obj.byteLength - byteOffset;
261+
262+ if (maxLength <= 0)
263+ throw new RangeError("'offset' is out of bounds");
264+
265+ if (length === undefined) {
266+ length = maxLength;
267+ } else {
268+ length >>>= 0;
269+ if (length > maxLength)
270+ throw new RangeError("'length' is out of bounds");
271+ }
258272
259- length >>>= 0;
260- return binding.createFromArrayBuffer(obj, byteOffset, length);
273+ return new FastBuffer(obj, byteOffset, length);
261274}
262275
263276function fromObject(obj) {
@@ -274,7 +287,7 @@ function fromObject(obj) {
274287 if (obj) {
275288 if (obj.buffer instanceof ArrayBuffer || 'length' in obj) {
276289 if (typeof obj.length !== 'number' || obj.length !== obj.length) {
277- return allocate(0 );
290+ return new FastBuffer( );
278291 }
279292 return fromArrayLike(obj);
280293 }
@@ -341,7 +354,7 @@ Buffer.concat = function(list, length) {
341354 throw new TypeError('"list" argument must be an Array of Buffers');
342355
343356 if (list.length === 0)
344- return Buffer.alloc(0 );
357+ return new FastBuffer( );
345358
346359 if (length === undefined) {
347360 length = 0;
@@ -818,10 +831,26 @@ Buffer.prototype.toJSON = function() {
818831};
819832
820833
834+ function adjustOffset(offset, length) {
835+ offset = +offset;
836+ if (offset === 0 || Number.isNaN(offset)) {
837+ return 0;
838+ }
839+ if (offset < 0) {
840+ offset += length;
841+ return offset > 0 ? offset : 0;
842+ } else {
843+ return offset < length ? offset : length;
844+ }
845+ }
846+
847+
821848Buffer.prototype.slice = function slice(start, end) {
822- const buffer = this.subarray(start, end);
823- Object.setPrototypeOf(buffer, Buffer.prototype);
824- return buffer;
849+ const srcLength = this.length;
850+ start = adjustOffset(start, srcLength);
851+ end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
852+ const newLength = end > start ? end - start : 0;
853+ return new FastBuffer(this.buffer, this.byteOffset + start, newLength);
825854};
826855
827856
0 commit comments