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 ;
@@ -63,24 +69,18 @@ Buffer.prototype.swap32 = function swap32() {
6369// do not own the ArrayBuffer allocator. Zero fill is always on in that case.
6470const zeroFill = bindingObj . zeroFill || [ 0 ] ;
6571
66- function createBuffer ( size , noZeroFill ) {
67- if ( noZeroFill )
68- zeroFill [ 0 ] = 0 ;
69-
72+ function createUnsafeBuffer ( size ) {
73+ zeroFill [ 0 ] = 0 ;
7074 try {
71- var ui8 = new Uint8Array ( size ) ;
75+ return new FastBuffer ( size ) ;
7276 } finally {
73- if ( noZeroFill )
74- zeroFill [ 0 ] = 1 ;
77+ zeroFill [ 0 ] = 1 ;
7578 }
76-
77- Object . setPrototypeOf ( ui8 , Buffer . prototype ) ;
78- return ui8 ;
7979}
8080
8181function createPool ( ) {
8282 poolSize = Buffer . poolSize ;
83- allocPool = createBuffer ( poolSize , true ) ;
83+ allocPool = createUnsafeBuffer ( poolSize ) ;
8484 poolOffset = 0 ;
8585}
8686createPool ( ) ;
@@ -138,7 +138,6 @@ Buffer.from = function(value, encodingOrOffset, length) {
138138 return fromObject ( value ) ;
139139} ;
140140
141- Object . setPrototypeOf ( Buffer . prototype , Uint8Array . prototype ) ;
142141Object . setPrototypeOf ( Buffer , Uint8Array ) ;
143142
144143function assertSize ( size ) {
@@ -158,18 +157,16 @@ function assertSize(size) {
158157 **/
159158Buffer . alloc = function ( size , fill , encoding ) {
160159 assertSize ( size ) ;
161- if ( size <= 0 )
162- return createBuffer ( size ) ;
163- if ( fill !== undefined ) {
160+ if ( size > 0 && fill !== undefined ) {
164161 // Since we are filling anyway, don't zero fill initially.
165162 // Only pay attention to encoding if it's a string. This
166163 // prevents accidentally sending in a number that would
167164 // be interpretted as a start offset.
168- return typeof encoding === 'string' ?
169- createBuffer ( size , true ) . fill ( fill , encoding ) :
170- createBuffer ( size , true ) . fill ( fill ) ;
165+ if ( typeof encoding !== 'string' )
166+ encoding = undefined ;
167+ return createUnsafeBuffer ( size ) . fill ( fill , encoding ) ;
171168 }
172- return createBuffer ( size ) ;
169+ return new FastBuffer ( size ) ;
173170} ;
174171
175172/**
@@ -188,15 +185,15 @@ Buffer.allocUnsafe = function(size) {
188185 **/
189186Buffer . allocUnsafeSlow = function ( size ) {
190187 assertSize ( size ) ;
191- return createBuffer ( size , true ) ;
188+ return createUnsafeBuffer ( size ) ;
192189} ;
193190
194191// If --zero-fill-buffers command line argument is set, a zero-filled
195192// buffer is returned.
196193function SlowBuffer ( length ) {
197194 if ( + length != length )
198195 length = 0 ;
199- return createBuffer ( + length , true ) ;
196+ return createUnsafeBuffer ( + length ) ;
200197}
201198
202199Object . setPrototypeOf ( SlowBuffer . prototype , Uint8Array . prototype ) ;
@@ -205,7 +202,7 @@ Object.setPrototypeOf(SlowBuffer, Uint8Array);
205202
206203function allocate ( size ) {
207204 if ( size <= 0 ) {
208- return createBuffer ( 0 ) ;
205+ return new FastBuffer ( ) ;
209206 }
210207 if ( size < ( Buffer . poolSize >>> 1 ) ) {
211208 if ( size > ( poolSize - poolOffset ) )
@@ -218,7 +215,7 @@ function allocate(size) {
218215 // Even though this is checked above, the conditional is a safety net and
219216 // sanity check to prevent any subsequent typed array allocation from not
220217 // being zero filled.
221- return createBuffer ( size , true ) ;
218+ return createUnsafeBuffer ( size ) ;
222219 }
223220}
224221
@@ -231,7 +228,7 @@ function fromString(string, encoding) {
231228 throw new TypeError ( '"encoding" must be a valid string encoding' ) ;
232229
233230 if ( string . length === 0 )
234- return Buffer . alloc ( 0 ) ;
231+ return new FastBuffer ( ) ;
235232
236233 var length = byteLength ( string , encoding ) ;
237234
@@ -251,18 +248,30 @@ function fromArrayLike(obj) {
251248 const length = obj . length ;
252249 const b = allocate ( length ) ;
253250 for ( var i = 0 ; i < length ; i ++ )
254- b [ i ] = obj [ i ] & 255 ;
251+ b [ i ] = obj [ i ] ;
255252 return b ;
256253}
257254
258255function fromArrayBuffer ( obj , byteOffset , length ) {
256+ if ( ! isArrayBuffer ( obj ) )
257+ throw new TypeError ( 'argument is not an ArrayBuffer' ) ;
258+
259259 byteOffset >>>= 0 ;
260260
261- if ( typeof length === 'undefined' )
262- return binding . createFromArrayBuffer ( obj , byteOffset ) ;
261+ const maxLength = obj . byteLength - byteOffset ;
262+
263+ if ( maxLength <= 0 )
264+ throw new RangeError ( "'offset' is out of bounds" ) ;
265+
266+ if ( length === undefined ) {
267+ length = maxLength ;
268+ } else {
269+ length >>>= 0 ;
270+ if ( length > maxLength )
271+ throw new RangeError ( "'length' is out of bounds" ) ;
272+ }
263273
264- length >>>= 0 ;
265- return binding . createFromArrayBuffer ( obj , byteOffset , length ) ;
274+ return new FastBuffer ( obj , byteOffset , length ) ;
266275}
267276
268277function fromObject ( obj ) {
@@ -279,7 +288,7 @@ function fromObject(obj) {
279288 if ( obj ) {
280289 if ( obj . buffer instanceof ArrayBuffer || 'length' in obj ) {
281290 if ( typeof obj . length !== 'number' || obj . length !== obj . length ) {
282- return allocate ( 0 ) ;
291+ return new FastBuffer ( ) ;
283292 }
284293 return fromArrayLike ( obj ) ;
285294 }
@@ -346,7 +355,7 @@ Buffer.concat = function(list, length) {
346355 throw new TypeError ( '"list" argument must be an Array of Buffers' ) ;
347356
348357 if ( list . length === 0 )
349- return Buffer . alloc ( 0 ) ;
358+ return new FastBuffer ( ) ;
350359
351360 if ( length === undefined ) {
352361 length = 0 ;
@@ -823,10 +832,26 @@ Buffer.prototype.toJSON = function() {
823832} ;
824833
825834
835+ function adjustOffset ( offset , length ) {
836+ offset = + offset ;
837+ if ( offset === 0 || Number . isNaN ( offset ) ) {
838+ return 0 ;
839+ }
840+ if ( offset < 0 ) {
841+ offset += length ;
842+ return offset > 0 ? offset : 0 ;
843+ } else {
844+ return offset < length ? offset : length ;
845+ }
846+ }
847+
848+
826849Buffer . prototype . slice = function slice ( start , end ) {
827- const buffer = this . subarray ( start , end ) ;
828- Object . setPrototypeOf ( buffer , Buffer . prototype ) ;
829- return buffer ;
850+ const srcLength = this . length ;
851+ start = adjustOffset ( start , srcLength ) ;
852+ end = end !== undefined ? adjustOffset ( end , srcLength ) : srcLength ;
853+ const newLength = end > start ? end - start : 0 ;
854+ return new FastBuffer ( this . buffer , this . byteOffset + start , newLength ) ;
830855} ;
831856
832857
0 commit comments