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