@@ -50,11 +50,22 @@ const {
5050 TypedArrayPrototypeGetByteOffset,
5151 TypedArrayPrototypeGetLength,
5252 TypedArrayPrototypeSet,
53- TypedArrayPrototypeSlice,
5453 TypedArrayPrototypeSubarray,
5554 Uint8Array,
55+ Uint8ArrayPrototype,
56+ uncurryThis,
5657} = primordials ;
5758
59+ // V8 shipping feature (toHex) is installed by
60+ // InitializeExperimentalGlobal(), which is skipped during snapshot creation
61+ // TODO: Remove this once V8 shipping feature (toHex) is available.
62+ let Uint8ArrayPrototypeToHex ;
63+ function ensureUint8ArrayToHex ( ) {
64+ if ( Uint8ArrayPrototypeToHex === undefined ) {
65+ Uint8ArrayPrototypeToHex = uncurryThis ( Uint8ArrayPrototype . toHex ) ;
66+ }
67+ }
68+
5869const {
5970 byteLengthUtf8,
6071 compare : _compare ,
@@ -383,28 +394,41 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
383394 return new FastBuffer ( ) ;
384395 }
385396
397+ const byteLength = TypedArrayPrototypeGetByteLength ( view ) ;
398+
386399 if ( offset !== undefined || length !== undefined ) {
387400 if ( offset !== undefined ) {
388401 validateInteger ( offset , 'offset' , 0 ) ;
389402 if ( offset >= viewLength ) return new FastBuffer ( ) ;
390403 } else {
391404 offset = 0 ;
392405 }
406+
393407 let end ;
394408 if ( length !== undefined ) {
395409 validateInteger ( length , 'length' , 0 ) ;
396- end = offset + length ;
410+ end = MathMin ( offset + length , viewLength ) ;
397411 } else {
398412 end = viewLength ;
399413 }
400414
401- view = TypedArrayPrototypeSlice ( view , offset , end ) ;
415+ if ( end <= offset ) return new FastBuffer ( ) ;
416+
417+ const elementSize = byteLength / viewLength ;
418+ const srcByteOffset = TypedArrayPrototypeGetByteOffset ( view ) +
419+ offset * elementSize ;
420+ const srcByteLength = ( end - offset ) * elementSize ;
421+
422+ return fromArrayLike ( new Uint8Array (
423+ TypedArrayPrototypeGetBuffer ( view ) ,
424+ srcByteOffset ,
425+ srcByteLength ) ) ;
402426 }
403427
404428 return fromArrayLike ( new Uint8Array (
405429 TypedArrayPrototypeGetBuffer ( view ) ,
406430 TypedArrayPrototypeGetByteOffset ( view ) ,
407- TypedArrayPrototypeGetByteLength ( view ) ) ) ;
431+ byteLength ) ) ;
408432} ;
409433
410434// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
@@ -551,14 +575,15 @@ function fromArrayBuffer(obj, byteOffset, length) {
551575}
552576
553577function fromArrayLike ( obj ) {
554- if ( obj . length <= 0 )
578+ const len = obj . length ;
579+ if ( len <= 0 )
555580 return new FastBuffer ( ) ;
556- if ( obj . length < ( Buffer . poolSize >>> 1 ) ) {
557- if ( obj . length > ( poolSize - poolOffset ) )
581+ if ( len < ( Buffer . poolSize >>> 1 ) ) {
582+ if ( len > ( poolSize - poolOffset ) )
558583 createPool ( ) ;
559- const b = new FastBuffer ( allocPool , poolOffset , obj . length ) ;
584+ const b = new FastBuffer ( allocPool , poolOffset , len ) ;
560585 TypedArrayPrototypeSet ( b , obj , 0 ) ;
561- poolOffset += obj . length ;
586+ poolOffset += len ;
562587 alignPool ( ) ;
563588 return b ;
564589 }
@@ -688,6 +713,14 @@ function base64ByteLength(str, bytes) {
688713 return ( bytes * 3 ) >>> 2 ;
689714}
690715
716+ function hexSliceToHex ( buf , start , end ) {
717+ ensureUint8ArrayToHex ( ) ;
718+ return Uint8ArrayPrototypeToHex (
719+ new Uint8Array ( TypedArrayPrototypeGetBuffer ( buf ) ,
720+ TypedArrayPrototypeGetByteOffset ( buf ) + start ,
721+ end - start ) ) ;
722+ }
723+
691724const encodingOps = {
692725 utf8 : {
693726 encoding : 'utf8' ,
@@ -732,11 +765,7 @@ const encodingOps = {
732765 write : asciiWrite ,
733766 slice : asciiSlice ,
734767 indexOf : ( buf , val , byteOffset , dir ) =>
735- indexOfBuffer ( buf ,
736- fromStringFast ( val , encodingOps . ascii ) ,
737- byteOffset ,
738- encodingsMap . ascii ,
739- dir ) ,
768+ indexOfString ( buf , val , byteOffset , encodingsMap . latin1 , dir ) ,
740769 } ,
741770 base64 : {
742771 encoding : 'base64' ,
@@ -769,7 +798,7 @@ const encodingOps = {
769798 encodingVal : encodingsMap . hex ,
770799 byteLength : ( string ) => string . length >>> 1 ,
771800 write : hexWrite ,
772- slice : hexSlice ,
801+ slice : hexSliceToHex ,
773802 indexOf : ( buf , val , byteOffset , dir ) =>
774803 indexOfBuffer ( buf ,
775804 fromStringFast ( val , encodingOps . hex ) ,
@@ -1118,7 +1147,7 @@ function _fill(buf, value, offset, end, encoding) {
11181147 value = 0 ;
11191148 } else if ( value . length === 1 ) {
11201149 // Fast path: If `value` fits into a single byte, use that numeric value.
1121- if ( normalizedEncoding === 'utf8' ) {
1150+ if ( normalizedEncoding === 'utf8' || normalizedEncoding === 'ascii' ) {
11221151 const code = StringPrototypeCharCodeAt ( value , 0 ) ;
11231152 if ( code < 128 ) {
11241153 value = code ;
@@ -1168,29 +1197,30 @@ function _fill(buf, value, offset, end, encoding) {
11681197}
11691198
11701199Buffer . prototype . write = function write ( string , offset , length , encoding ) {
1200+ const len = this . length ;
11711201 // Buffer#write(string);
11721202 if ( offset === undefined ) {
1173- return utf8Write ( this , string , 0 , this . length ) ;
1203+ return utf8Write ( this , string , 0 , len ) ;
11741204 }
11751205 // Buffer#write(string, encoding)
11761206 if ( length === undefined && typeof offset === 'string' ) {
11771207 encoding = offset ;
1178- length = this . length ;
1208+ length = len ;
11791209 offset = 0 ;
11801210
11811211 // Buffer#write(string, offset[, length][, encoding])
11821212 } else {
1183- validateOffset ( offset , 'offset' , 0 , this . length ) ;
1213+ validateOffset ( offset , 'offset' , 0 , len ) ;
11841214
1185- const remaining = this . length - offset ;
1215+ const remaining = len - offset ;
11861216
11871217 if ( length === undefined ) {
11881218 length = remaining ;
11891219 } else if ( typeof length === 'string' ) {
11901220 encoding = length ;
11911221 length = remaining ;
11921222 } else {
1193- validateOffset ( length , 'length' , 0 , this . length ) ;
1223+ validateOffset ( length , 'length' , 0 , len ) ;
11941224 if ( length > remaining )
11951225 length = remaining ;
11961226 }
@@ -1208,9 +1238,10 @@ Buffer.prototype.write = function write(string, offset, length, encoding) {
12081238} ;
12091239
12101240Buffer . prototype . toJSON = function toJSON ( ) {
1211- if ( this . length > 0 ) {
1212- const data = new Array ( this . length ) ;
1213- for ( let i = 0 ; i < this . length ; ++ i )
1241+ const len = this . length ;
1242+ if ( len > 0 ) {
1243+ const data = new Array ( len ) ;
1244+ for ( let i = 0 ; i < len ; ++ i )
12141245 data [ i ] = this [ i ] ;
12151246 return { type : 'Buffer' , data } ;
12161247 }
@@ -1264,7 +1295,8 @@ Buffer.prototype.swap16 = function swap16() {
12641295 swap ( this , i , i + 1 ) ;
12651296 return this ;
12661297 }
1267- return _swap16 ( this ) ;
1298+ _swap16 ( this ) ;
1299+ return this ;
12681300} ;
12691301
12701302Buffer . prototype . swap32 = function swap32 ( ) {
@@ -1281,7 +1313,8 @@ Buffer.prototype.swap32 = function swap32() {
12811313 }
12821314 return this ;
12831315 }
1284- return _swap32 ( this ) ;
1316+ _swap32 ( this ) ;
1317+ return this ;
12851318} ;
12861319
12871320Buffer . prototype . swap64 = function swap64 ( ) {
@@ -1300,7 +1333,8 @@ Buffer.prototype.swap64 = function swap64() {
13001333 }
13011334 return this ;
13021335 }
1303- return _swap64 ( this ) ;
1336+ _swap64 ( this ) ;
1337+ return this ;
13041338} ;
13051339
13061340Buffer . prototype . toLocaleString = Buffer . prototype . toString ;
0 commit comments