@@ -616,66 +616,51 @@ Buffer.concat = function concat(list, length) {
616616 if ( list . length === 0 )
617617 return new FastBuffer ( ) ;
618618
619- if ( length === undefined ) {
619+ const autoLength = length === undefined ;
620+ if ( autoLength ) {
620621 length = 0 ;
621- for ( let i = 0 ; i < list . length ; i ++ ) {
622- const buf = list [ i ] ;
623- if ( ! isUint8Array ( buf ) ) {
624- // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
625- // Instead, find the proper error code for this.
626- throw new ERR_INVALID_ARG_TYPE (
627- `list[${ i } ]` , [ 'Buffer' , 'Uint8Array' ] , buf ) ;
628- }
629- length += TypedArrayPrototypeGetByteLength ( buf ) ;
630- }
631-
632- const buffer = allocate ( length ) ;
633- let pos = 0 ;
634- for ( let i = 0 ; i < list . length ; i ++ ) {
635- const buf = list [ i ] ;
636- const bufLength = TypedArrayPrototypeGetByteLength ( buf ) ;
637- TypedArrayPrototypeSet ( buffer , buf , pos ) ;
638- pos += bufLength ;
639- }
640-
641- if ( pos < length ) {
642- TypedArrayPrototypeFill ( buffer , 0 , pos , length ) ;
643- }
644- return buffer ;
622+ } else {
623+ validateOffset ( length , 'length' ) ;
645624 }
646625
647- validateOffset ( length , 'length' ) ;
648- for ( let i = 0 ; i < list . length ; i ++ ) {
649- if ( ! isUint8Array ( list [ i ] ) ) {
650- // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
651- // Instead, find the proper error code for this.
652- throw new ERR_INVALID_ARG_TYPE (
653- `list[${ i } ]` , [ 'Buffer' , 'Uint8Array' ] , list [ i ] ) ;
626+ let i = 0 ;
627+ let j = 0 ;
628+ let pos = 0 ;
629+ const postPositions = new Array ( list . length ) ;
630+ try {
631+ for ( ; i < list . length ; i ++ ) {
632+ pos += TypedArrayPrototypeGetByteLength ( list [ i ] ) ;
633+ postPositions [ i ] = pos ;
634+ j += pos <= length ;
654635 }
636+ } catch {
637+ // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
638+ // Instead, find the proper error code for this.
639+ throw new ERR_INVALID_ARG_TYPE (
640+ `list[${ i } ]` , [ 'Buffer' , 'Uint8Array' ] , list [ i ] ) ;
641+ }
642+ if ( autoLength ) {
643+ length = pos ;
644+ j = list . length ;
655645 }
656646
657647 const buffer = allocate ( length ) ;
658- let pos = 0 ;
659- for ( let i = 0 ; i < list . length ; i ++ ) {
660- const buf = list [ i ] ;
661- const bufLength = TypedArrayPrototypeGetByteLength ( buf ) ;
662- if ( pos + bufLength > length ) {
663- TypedArrayPrototypeSet ( buffer ,
664- TypedArrayPrototypeSubarray ( buf , 0 , length - pos ) ,
665- pos ) ;
666- pos = length ;
667- break ;
668- }
669- TypedArrayPrototypeSet ( buffer , buf , pos ) ;
670- pos += bufLength ;
648+ // Copy from every input that fits completely.
649+ for ( pos = i = 0 ; i < j ; i ++ ) {
650+ TypedArrayPrototypeSet ( buffer , list [ i ] , pos ) ;
651+ pos = postPositions [ i ] ;
671652 }
672653
673- // Note: `length` is always equal to `buffer.length` at this point
674654 if ( pos < length ) {
675- // Zero-fill the remaining bytes if the specified `length` was more than
676- // the actual total length, i.e. if we have some remaining allocated bytes
677- // there were not initialized.
678- TypedArrayPrototypeFill ( buffer , 0 , pos , length ) ;
655+ // Populate the remaining bytes, either by partially consuming the next
656+ // input or by zero-filling.
657+ if ( j < list . length ) {
658+ TypedArrayPrototypeSet ( buffer ,
659+ TypedArrayPrototypeSubarray ( list [ j ] , 0 , length - pos ) ,
660+ pos ) ;
661+ } else {
662+ TypedArrayPrototypeFill ( buffer , 0 , pos , length ) ;
663+ }
679664 }
680665
681666 return buffer ;
0 commit comments