@@ -1188,7 +1188,7 @@ const b8 = (d: Uint8Array, b: number) => b4(d, b) + (b4(d, b + 4) * 4294967296);
11881188
11891189// write bytes, works only for values <= uint32
11901190const wbytes = ( d : Uint8Array , b : number , v : number ) => {
1191- for ( ; v ; ++ b ) d [ b ] = v , v >>>= 8 ;
1191+ for ( ; v ; v >>>= 8 ) d [ b ++ ] = v ;
11921192}
11931193
11941194const wbytes64 = ( d : Uint8Array , b : number , v : number ) => {
@@ -2712,31 +2712,47 @@ const slzh = (d: Uint8Array, b: number) => b + 30 + b2(d, b + 26) + b2(d, b + 28
27122712
27132713// read zip header
27142714const zh = ( d : Uint8Array , b : number ) => {
2715- const u = b2 ( d , b + 8 ) & 2048 ,
2715+ let u = b2 ( d , b + 8 ) & 2048 ,
27162716 cm = b2 ( d , b + 10 ) ,
27172717 sc = b4 ( d , b + 20 ) ,
27182718 su = b4 ( d , b + 24 ) ,
27192719 fnl = b2 ( d , b + 28 ) ,
27202720 exl = b2 ( d , b + 30 ) ,
27212721 fcl = b2 ( d , b + 32 ) ,
27222722 lo = b4 ( d , b + 42 ) ,
2723- fn = strFromU8 ( d . subarray ( b += 46 , b += fnl ) , ! u ) ;
2724- if ( su == f8 ) {
2725- const ef = z64e ( d , b , exl ) ;
2726- if ( ef ) return [ cm , ef ( sc , 12 ) , ef ( su , 4 ) , fn , b + exl + fcl , ef ( lo , 20 ) ] as const ;
2727- }
2723+ fn = strFromU8 ( d . subarray ( b += 46 , b += fnl ) , ! u ) ,
2724+ ef = su == f8 && z64e ( d , b , exl ) ;
2725+ if ( ef ) su = ef ( su , 4 ) , sc = ef ( sc , 12 ) , lo = ef ( lo , 20 ) ;
27282726 return [ cm , sc , su , fn , b + exl + fcl , lo ] as const ;
27292727}
27302728
27312729// read zip64 extra field
27322730const z64e = ( d : Uint8Array , b : number , exl : number ) => {
2733- let e = b + exl , id : number , l : number ;
2731+ let e = b + exl , l : number ;
27342732 for ( ; b < e ; b += 4 + l ) {
2735- id = b2 ( d , b ) , l = b2 ( d , b + 2 ) ;
2736- if ( id == 1 ) return < T > ( v : T , o : 4 | 12 | 20 ) => l > o ? b8 ( d , b + o ) : v ;
2733+ l = b2 ( d , b + 2 ) ;
2734+ if ( b2 ( d , b ) == 1 ) return < T > ( v : T , o : 4 | 12 | 20 ) => l > o ? b8 ( d , b + o ) : v ;
27372735 }
27382736}
27392737
2738+ // read zip footer
2739+ const zf = ( d : Uint8Array ) => {
2740+ let e = d . length - 22 , fl : number , cdo : number ;
2741+ for ( ; b4 ( d , e ) != 0x6054B50 ; -- e ) {
2742+ if ( ! e || d . length - e > 65558 ) err ( 13 ) ;
2743+ }
2744+ fl = b2 ( d , e + 8 ) ;
2745+ cdo = b4 ( d , e + 16 ) ;
2746+ if ( fl == f4 || cdo == f8 ) {
2747+ e = b8 ( d , e - 12 ) ;
2748+ if ( b4 ( d , e ) == 0x6064B50 ) {
2749+ fl = b8 ( d , e + 32 ) ;
2750+ cdo = b8 ( d , e + 48 ) ;
2751+ }
2752+ }
2753+ return [ fl , cdo ] as const ;
2754+ }
2755+
27402756interface ZipFileEntry {
27412757 // file name
27422758 fn : Uint8Array ;
@@ -3198,6 +3214,9 @@ export class Zip {
31983214 this . terminate ( ) ;
31993215 } else {
32003216 sc += dc . length ;
3217+ if ( final ) {
3218+ f . su = file . size , f . sc = sc , f . cr = file . crc ;
3219+ }
32013220 if ( ! lh ) {
32023221 ddl = final ? 0 : z64 ? 24 : 16 ;
32033222 if ( ddl ) {
@@ -3206,9 +3225,6 @@ export class Zip {
32063225 // mark the Data Descriptor format as Zip64
32073226 f . ex = mrg ( ex , { 1 : [ ] } ) ;
32083227 }
3209- } else {
3210- // first and final chunk - DD is not necessary
3211- f . su = file . size , f . sc = sc , f . cr = file . crc ;
32123228 }
32133229 lh = wzh ( f ) , f . ex = ex ;
32143230 const d = new u8 ( lh . l ) ;
@@ -3217,7 +3233,7 @@ export class Zip {
32173233 }
32183234 chks . push ( dc ) ;
32193235 if ( final ) {
3220- f . su = file . size , f . sc = sc , f . cr = file . crc , f . b = lh . l + sc + ddl ;
3236+ f . b = lh . l + sc + ddl ;
32213237 if ( ddl ) {
32223238 const d = new u8 ( ddl ) ;
32233239 wbytes ( d , 0 , 0x8074B50 ) ;
@@ -3266,16 +3282,18 @@ export class Zip {
32663282 }
32673283
32683284 private e ( ) {
3269- const files = this . u ;
3285+ const files = this . u , fl = files . length ;
32703286 let o = 0 , cdl = 0 ;
3271- for ( const f of files ) {
3287+ for ( let i = 0 ; i < fl ; ++ i ) {
3288+ const f = files [ i ] ;
32723289 f . ch = wzh ( f , o ) ;
32733290 f . c = cdl ;
32743291 o += f . b , cdl += f . ch . l ;
32753292 }
3276- const eocd = wzf ( files . length , cdl , o ) ;
3293+ const eocd = wzf ( fl , cdl , o ) ;
32773294 const out = new u8 ( cdl + eocd . l ) ;
3278- for ( const f of files ) {
3295+ for ( let i = 0 ; i < fl ; ++ i ) {
3296+ const f = files [ i ] ;
32793297 f . ch ( out , f . c ) ;
32803298 }
32813299 eocd ( out , cdl ) ;
@@ -3331,15 +3349,17 @@ export function zip(data: AsyncZippable, opts: AsyncZipOptions | FlateCallback,
33313349 mt ( ( ) => { cbd = cb ; } ) ;
33323350 const cbf = ( ) => {
33333351 let o = 0 , cdl = 0 ;
3334- for ( const f of files ) {
3352+ for ( let i = 0 ; i < fl ; ++ i ) {
3353+ const f = files [ i ] ;
33353354 f . lh = wzh ( f ) ;
33363355 f . ch = wzh ( f , o ) ;
33373356 f . o = o ;
33383357 o += f . lh . l + f . sc , cdl += f . ch . l ;
33393358 }
33403359 const eocd = wzf ( fl , cdl , o ) ;
33413360 const out = new u8 ( o + cdl + eocd . l ) ;
3342- for ( const f of files ) {
3361+ for ( let i = 0 ; i < fl ; ++ i ) {
3362+ const f = files [ i ] ;
33433363 f . lh ( out , f . o ) ;
33443364 out . set ( f . dc , f . o + f . lh . l ) ;
33453365 f . ch ( out , o ) ;
@@ -3396,7 +3416,7 @@ export function zipSync(data: Zippable, opts?: ZipOptions) {
33963416 const r : FlatZippable < false > = { } ;
33973417 const files : BufferedZipFileEntry [ ] = [ ] ;
33983418 fltn ( data , '' , r , opts ) ;
3399- let o = 0 , cdl = 0 ;
3419+ let o = 0 , cdl = 0 , fl : number ;
34003420 for ( const fns in r ) {
34013421 const [ du , zo ] = r [ fns ] ;
34023422 const c = crc ( ) ;
@@ -3413,9 +3433,10 @@ export function zipSync(data: Zippable, opts?: ZipOptions) {
34133433 files . push ( f ) ;
34143434 o += f . lh . l + f . sc , cdl += f . ch . l ;
34153435 }
3416- const eocd = wzf ( files . length , cdl , o ) ;
3436+ const eocd = wzf ( fl = files . length , cdl , o ) ;
34173437 const out = new u8 ( o + cdl + eocd . l ) ;
3418- for ( const f of files ) {
3438+ for ( let i = 0 ; i < fl ; ++ i ) {
3439+ const f = files [ i ] ;
34193440 f . lh ( out , f . o ) ;
34203441 out . set ( f . dc , f . o + f . lh . l ) ;
34213442 f . ch ( out , o ) ;
@@ -3682,11 +3703,11 @@ export class Unzip {
36823703 const g = b2 ( buf , i + 6 ) , dd = g & 8 , u = g & 2048 , cm = b2 ( buf , i + 8 ) ;
36833704 let sc = b4 ( buf , i + 18 ) , su = b4 ( buf , i + 22 ) ;
36843705 const fn = strFromU8 ( buf . subarray ( i += 30 , i += fnl ) , ! u ) ;
3706+ const ef = su == f8 && z64e ( buf , i , exl ) ;
36853707 if ( dd ) {
36863708 sc = z64e ( buf , i , exl ) ? - 2 : - 1 ;
3687- } else if ( su == f8 ) {
3688- const ef = z64e ( buf , i , exl ) ;
3689- if ( ef ) su = ef ( su , 4 ) , sc = ef ( sc , 12 ) ;
3709+ } else if ( ef ) {
3710+ su = ef ( su , 4 ) , sc = ef ( sc , 12 ) ;
36903711 }
36913712 i += exl ;
36923713 this . c = sc ;
@@ -3784,27 +3805,11 @@ export function unzip(data: Uint8Array, opts: AsyncUnzipOptions | UnzipCallback,
37843805 mt ( ( ) => { cb ( a , b ) ; } ) ;
37853806 }
37863807 mt ( ( ) => { cbd = cb ; } ) ;
3787- let e = data . length - 22 ;
3788- for ( ; b4 ( data , e ) != 0x6054B50 ; -- e ) {
3789- if ( ! e || data . length - e > 65558 ) {
3790- cbd ( err ( 13 , 0 , 1 ) , null ) ;
3791- return tAll ;
3792- }
3793- }
3794- let lft = b2 ( data , e + 8 ) ;
3795- if ( lft ) {
3796- let c = lft ;
3797- let o = b4 ( data , e + 16 ) ;
3798- if ( o == f8 || c == f4 ) {
3799- let ze = b8 ( data , e - 12 ) ;
3800- if ( b4 ( data , ze ) == 0x6064B50 ) {
3801- c = lft = b8 ( data , ze + 32 ) ;
3802- o = b8 ( data , ze + 48 ) ;
3803- }
3804- }
3808+ try {
38053809 const files : Unzipped = { } ;
3806- const fltr = opts && ( opts as AsyncUnzipOptions ) . filter ;
3807- for ( let i = 0 ; i < c ; ++ i ) {
3810+ const fltr = ( opts as AsyncUnzipOptions ) . filter ;
3811+ let [ fl , o ] = zf ( data ) , lft = fl ;
3812+ for ( let i = 0 ; i < fl ; ++ i ) {
38083813 const [ cm , sc , su , fn , no , off ] = zh ( data , o ) , b = slzh ( data , off ) ;
38093814 o = no
38103815 const cbl : FlateCallback = ( e , du ) => {
@@ -3827,17 +3832,18 @@ export function unzip(data: Uint8Array, opts: AsyncUnzipOptions | UnzipCallback,
38273832 const dc = data . subarray ( b , b + sc ) ;
38283833 // Synchronously decompress under 512KB, or barely-compressed data
38293834 if ( su < 524288 || sc > 0.8 * su ) {
3830- try {
3831- cbl ( null , inflateSync ( dc , { out : new u8 ( su ) } ) ) ;
3832- } catch ( e ) {
3833- cbl ( e , null ) ;
3834- }
3835+ cbl ( null , inflateSync ( dc , { out : new u8 ( su ) } ) ) ;
3836+ } else {
3837+ term . push ( inflate ( dc , { size : su } , cbl ) ) ;
38353838 }
3836- else term . push ( inflate ( dc , { size : su } , cbl ) ) ;
3837- } else cbl ( err ( 14 , 'unknown compression type ' + cm , 1 ) , null ) ;
3839+ } else err ( 14 , 'unknown compression type ' + cm ) ;
38383840 } else cbl ( null , null ) ;
38393841 }
3840- } else cbd ( null , { } ) ;
3842+ if ( ! fl ) cbd ( null , files ) ;
3843+ } catch ( e ) {
3844+ tAll ( ) ;
3845+ cbd ( e , null ) ;
3846+ }
38413847 return tAll ;
38423848}
38433849
@@ -3850,22 +3856,9 @@ export function unzip(data: Uint8Array, opts: AsyncUnzipOptions | UnzipCallback,
38503856 */
38513857export function unzipSync ( data : Uint8Array , opts ?: UnzipOptions ) {
38523858 const files : Unzipped = { } ;
3853- let e = data . length - 22 ;
3854- for ( ; b4 ( data , e ) != 0x6054B50 ; -- e ) {
3855- if ( ! e || data . length - e > 65558 ) err ( 13 ) ;
3856- }
3857- let c = b2 ( data , e + 8 ) ;
3858- if ( ! c ) return { } ;
3859- let o = b4 ( data , e + 16 ) ;
3860- if ( o == f8 || c == f4 ) {
3861- let ze = b8 ( data , e - 12 ) ;
3862- if ( b4 ( data , ze ) == 0x6064B50 ) {
3863- c = b8 ( data , ze + 32 ) ;
3864- o = b8 ( data , ze + 48 ) ;
3865- }
3866- }
38673859 const fltr = opts && opts . filter ;
3868- for ( let i = 0 ; i < c ; ++ i ) {
3860+ let [ fl , o ] = zf ( data ) ;
3861+ for ( let i = 0 ; i < fl ; ++ i ) {
38693862 const [ cm , sc , su , fn , no , off ] = zh ( data , o ) , b = slzh ( data , off ) ;
38703863 o = no ;
38713864 if ( ! fltr || fltr ( {
0 commit comments