@@ -50,10 +50,21 @@ const {
5050 TypedArrayPrototypeGetByteOffset,
5151 TypedArrayPrototypeGetLength,
5252 TypedArrayPrototypeSet,
53- TypedArrayPrototypeSlice,
5453 Uint8Array,
54+ Uint8ArrayPrototype,
55+ uncurryThis,
5556} = primordials ;
5657
58+ // V8 shipping feature (toHex) is installed by
59+ // InitializeExperimentalGlobal(), which is skipped during snapshot creation
60+ // TODO: Remove this once V8 shipping feature (toHex) is available.
61+ let Uint8ArrayPrototypeToHex ;
62+ function ensureUint8ArrayToHex ( ) {
63+ if ( Uint8ArrayPrototypeToHex === undefined ) {
64+ Uint8ArrayPrototypeToHex = uncurryThis ( Uint8ArrayPrototype . toHex ) ;
65+ }
66+ }
67+
5768const {
5869 byteLengthUtf8,
5970 compare : _compare ,
@@ -382,28 +393,41 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
382393 return new FastBuffer ( ) ;
383394 }
384395
396+ const byteLength = TypedArrayPrototypeGetByteLength ( view ) ;
397+
385398 if ( offset !== undefined || length !== undefined ) {
386399 if ( offset !== undefined ) {
387400 validateInteger ( offset , 'offset' , 0 ) ;
388401 if ( offset >= viewLength ) return new FastBuffer ( ) ;
389402 } else {
390403 offset = 0 ;
391404 }
405+
392406 let end ;
393407 if ( length !== undefined ) {
394408 validateInteger ( length , 'length' , 0 ) ;
395- end = offset + length ;
409+ end = MathMin ( offset + length , viewLength ) ;
396410 } else {
397411 end = viewLength ;
398412 }
399413
400- view = TypedArrayPrototypeSlice ( view , offset , end ) ;
414+ if ( end <= offset ) return new FastBuffer ( ) ;
415+
416+ const elementSize = byteLength / viewLength ;
417+ const srcByteOffset = TypedArrayPrototypeGetByteOffset ( view ) +
418+ offset * elementSize ;
419+ const srcByteLength = ( end - offset ) * elementSize ;
420+
421+ return fromArrayLike ( new Uint8Array (
422+ TypedArrayPrototypeGetBuffer ( view ) ,
423+ srcByteOffset ,
424+ srcByteLength ) ) ;
401425 }
402426
403427 return fromArrayLike ( new Uint8Array (
404428 TypedArrayPrototypeGetBuffer ( view ) ,
405429 TypedArrayPrototypeGetByteOffset ( view ) ,
406- TypedArrayPrototypeGetByteLength ( view ) ) ) ;
430+ byteLength ) ) ;
407431} ;
408432
409433// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
@@ -550,14 +574,15 @@ function fromArrayBuffer(obj, byteOffset, length) {
550574}
551575
552576function fromArrayLike ( obj ) {
553- if ( obj . length <= 0 )
577+ const len = obj . length ;
578+ if ( len <= 0 )
554579 return new FastBuffer ( ) ;
555- if ( obj . length < ( Buffer . poolSize >>> 1 ) ) {
556- if ( obj . length > ( poolSize - poolOffset ) )
580+ if ( len < ( Buffer . poolSize >>> 1 ) ) {
581+ if ( len > ( poolSize - poolOffset ) )
557582 createPool ( ) ;
558- const b = new FastBuffer ( allocPool , poolOffset , obj . length ) ;
583+ const b = new FastBuffer ( allocPool , poolOffset , len ) ;
559584 TypedArrayPrototypeSet ( b , obj , 0 ) ;
560- poolOffset += obj . length ;
585+ poolOffset += len ;
561586 alignPool ( ) ;
562587 return b ;
563588 }
@@ -657,6 +682,14 @@ function base64ByteLength(str, bytes) {
657682 return ( bytes * 3 ) >>> 2 ;
658683}
659684
685+ function hexSliceToHex ( buf , start , end ) {
686+ ensureUint8ArrayToHex ( ) ;
687+ return Uint8ArrayPrototypeToHex (
688+ new Uint8Array ( TypedArrayPrototypeGetBuffer ( buf ) ,
689+ TypedArrayPrototypeGetByteOffset ( buf ) + start ,
690+ end - start ) ) ;
691+ }
692+
660693const encodingOps = {
661694 utf8 : {
662695 encoding : 'utf8' ,
@@ -701,11 +734,7 @@ const encodingOps = {
701734 write : asciiWrite ,
702735 slice : asciiSlice ,
703736 indexOf : ( buf , val , byteOffset , dir ) =>
704- indexOfBuffer ( buf ,
705- fromStringFast ( val , encodingOps . ascii ) ,
706- byteOffset ,
707- encodingsMap . ascii ,
708- dir ) ,
737+ indexOfString ( buf , val , byteOffset , encodingsMap . latin1 , dir ) ,
709738 } ,
710739 base64 : {
711740 encoding : 'base64' ,
@@ -738,7 +767,7 @@ const encodingOps = {
738767 encodingVal : encodingsMap . hex ,
739768 byteLength : ( string ) => string . length >>> 1 ,
740769 write : hexWrite ,
741- slice : hexSlice ,
770+ slice : hexSliceToHex ,
742771 indexOf : ( buf , val , byteOffset , dir ) =>
743772 indexOfBuffer ( buf ,
744773 fromStringFast ( val , encodingOps . hex ) ,
@@ -1087,7 +1116,7 @@ function _fill(buf, value, offset, end, encoding) {
10871116 value = 0 ;
10881117 } else if ( value . length === 1 ) {
10891118 // Fast path: If `value` fits into a single byte, use that numeric value.
1090- if ( normalizedEncoding === 'utf8' ) {
1119+ if ( normalizedEncoding === 'utf8' || normalizedEncoding === 'ascii' ) {
10911120 const code = StringPrototypeCharCodeAt ( value , 0 ) ;
10921121 if ( code < 128 ) {
10931122 value = code ;
@@ -1137,29 +1166,30 @@ function _fill(buf, value, offset, end, encoding) {
11371166}
11381167
11391168Buffer . prototype . write = function write ( string , offset , length , encoding ) {
1169+ const len = this . length ;
11401170 // Buffer#write(string);
11411171 if ( offset === undefined ) {
1142- return utf8Write ( this , string , 0 , this . length ) ;
1172+ return utf8Write ( this , string , 0 , len ) ;
11431173 }
11441174 // Buffer#write(string, encoding)
11451175 if ( length === undefined && typeof offset === 'string' ) {
11461176 encoding = offset ;
1147- length = this . length ;
1177+ length = len ;
11481178 offset = 0 ;
11491179
11501180 // Buffer#write(string, offset[, length][, encoding])
11511181 } else {
1152- validateOffset ( offset , 'offset' , 0 , this . length ) ;
1182+ validateOffset ( offset , 'offset' , 0 , len ) ;
11531183
1154- const remaining = this . length - offset ;
1184+ const remaining = len - offset ;
11551185
11561186 if ( length === undefined ) {
11571187 length = remaining ;
11581188 } else if ( typeof length === 'string' ) {
11591189 encoding = length ;
11601190 length = remaining ;
11611191 } else {
1162- validateOffset ( length , 'length' , 0 , this . length ) ;
1192+ validateOffset ( length , 'length' , 0 , len ) ;
11631193 if ( length > remaining )
11641194 length = remaining ;
11651195 }
@@ -1177,9 +1207,10 @@ Buffer.prototype.write = function write(string, offset, length, encoding) {
11771207} ;
11781208
11791209Buffer . prototype . toJSON = function toJSON ( ) {
1180- if ( this . length > 0 ) {
1181- const data = new Array ( this . length ) ;
1182- for ( let i = 0 ; i < this . length ; ++ i )
1210+ const len = this . length ;
1211+ if ( len > 0 ) {
1212+ const data = new Array ( len ) ;
1213+ for ( let i = 0 ; i < len ; ++ i )
11831214 data [ i ] = this [ i ] ;
11841215 return { type : 'Buffer' , data } ;
11851216 }
@@ -1233,7 +1264,8 @@ Buffer.prototype.swap16 = function swap16() {
12331264 swap ( this , i , i + 1 ) ;
12341265 return this ;
12351266 }
1236- return _swap16 ( this ) ;
1267+ _swap16 ( this ) ;
1268+ return this ;
12371269} ;
12381270
12391271Buffer . prototype . swap32 = function swap32 ( ) {
@@ -1250,7 +1282,8 @@ Buffer.prototype.swap32 = function swap32() {
12501282 }
12511283 return this ;
12521284 }
1253- return _swap32 ( this ) ;
1285+ _swap32 ( this ) ;
1286+ return this ;
12541287} ;
12551288
12561289Buffer . prototype . swap64 = function swap64 ( ) {
@@ -1269,7 +1302,8 @@ Buffer.prototype.swap64 = function swap64() {
12691302 }
12701303 return this ;
12711304 }
1272- return _swap64 ( this ) ;
1305+ _swap64 ( this ) ;
1306+ return this ;
12731307} ;
12741308
12751309Buffer . prototype . toLocaleString = Buffer . prototype . toString ;
0 commit comments