@zip.js/zip.js 2.14.0 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/BENCHMARKS.md +350 -454
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +342 -120
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +340 -113
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +342 -120
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +340 -113
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +342 -120
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +342 -115
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +346 -124
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +342 -115
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-module.wasm +0 -0
  20. package/dist/zip-native.js +342 -115
  21. package/dist/zip-native.min.js +1 -1
  22. package/dist/zip-web-worker-native.js +1 -1
  23. package/dist/zip-web-worker.js +1 -1
  24. package/dist/zip.js +346 -124
  25. package/dist/zip.min.js +1 -1
  26. package/index-native.cjs +342 -115
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +346 -124
  29. package/index.d.cts +20 -13
  30. package/index.d.ts +20 -13
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-pool.js +35 -19
  33. package/lib/core/codec-worker.js +9 -6
  34. package/lib/core/streams/codecs/aes-hmac-sha1.js +194 -56
  35. package/lib/core/streams/zip-entry-stream.js +18 -10
  36. package/lib/core/streams/zlib-wasm/zlib-streams.js +2 -7
  37. package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
  38. package/lib/core/util/decode-text.js +15 -1
  39. package/lib/core/version.js +1 -1
  40. package/lib/core/web-worker-inline-native.js +1 -1
  41. package/lib/core/web-worker-inline-wasm.js +1 -1
  42. package/lib/core/zip-reader.js +65 -16
  43. package/lib/core/zlib-streams-inline.js +1 -1
  44. package/package.json +1 -1
package/dist/zip-core.js CHANGED
@@ -736,7 +736,7 @@
736
736
  const ROUND_KEYS_LENGTH = 60;
737
737
  const SHA1_BLOCK_LENGTH = 64;
738
738
  const SHA1_DIGEST_LENGTH = 20;
739
- const SHA1_SCHEDULE_LENGTH = 80;
739
+ const SHA1_SCHEDULE_LENGTH = 16;
740
740
  const SHA1_LENGTH_OFFSET = 56;
741
741
  const SHA1_PADDING = new Uint8Array([0x80]);
742
742
  const SHA1_ZERO = new Uint8Array(1);
@@ -755,9 +755,12 @@
755
755
  initTables();
756
756
  const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
757
757
  const rounds = expandKey(key, roundKeys);
758
- const counter = new Uint8Array(BLOCK_LENGTH$1);
759
758
  const keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
760
759
  const hmac = createHmac(authenticationKey);
760
+ let counter0 = 0;
761
+ let counter1 = 0;
762
+ let counter2 = 0;
763
+ let counter3 = 0;
761
764
  return {
762
765
  process(data, decrypt) {
763
766
  if (decrypt) {
@@ -793,31 +796,83 @@
793
796
  }
794
797
 
795
798
  function nextKeystream() {
796
- for (let indexByte = 0; indexByte < BLOCK_LENGTH$1; indexByte++) {
797
- counter[indexByte]++;
798
- if (counter[indexByte] !== 0) {
799
- break;
800
- }
801
- }
802
- let s0 = ((counter[0] << 24) | (counter[1] << 16) | (counter[2] << 8) | counter[3]) ^ roundKeys[0];
803
- let s1 = ((counter[4] << 24) | (counter[5] << 16) | (counter[6] << 8) | counter[7]) ^ roundKeys[1];
804
- let s2 = ((counter[8] << 24) | (counter[9] << 16) | (counter[10] << 8) | counter[11]) ^ roundKeys[2];
805
- let s3 = ((counter[12] << 24) | (counter[13] << 16) | (counter[14] << 8) | counter[15]) ^ roundKeys[3];
806
- let indexKey = 4;
807
- for (let round = 1; round < rounds; round++, indexKey += 4) {
808
- const t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[indexKey];
809
- const t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[indexKey + 1];
810
- const t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[indexKey + 2];
811
- const t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[indexKey + 3];
812
- s0 = t0;
813
- s1 = t1;
814
- s2 = t2;
815
- s3 = t3;
816
- }
817
- keystream[0] = ((S_BOX[s0 >>> 24] << 24) | (S_BOX[(s1 >>> 16) & 255] << 16) | (S_BOX[(s2 >>> 8) & 255] << 8) | S_BOX[s3 & 255]) ^ roundKeys[indexKey];
818
- keystream[1] = ((S_BOX[s1 >>> 24] << 24) | (S_BOX[(s2 >>> 16) & 255] << 16) | (S_BOX[(s3 >>> 8) & 255] << 8) | S_BOX[s0 & 255]) ^ roundKeys[indexKey + 1];
819
- keystream[2] = ((S_BOX[s2 >>> 24] << 24) | (S_BOX[(s3 >>> 16) & 255] << 16) | (S_BOX[(s0 >>> 8) & 255] << 8) | S_BOX[s1 & 255]) ^ roundKeys[indexKey + 2];
820
- keystream[3] = ((S_BOX[s3 >>> 24] << 24) | (S_BOX[(s0 >>> 16) & 255] << 16) | (S_BOX[(s1 >>> 8) & 255] << 8) | S_BOX[s2 & 255]) ^ roundKeys[indexKey + 3];
799
+ counter0 = (counter0 + 1) | 0;
800
+ if (!counter0) {
801
+ counter1 = (counter1 + 1) | 0;
802
+ if (!counter1) {
803
+ counter2 = (counter2 + 1) | 0;
804
+ if (!counter2) {
805
+ counter3 = (counter3 + 1) | 0;
806
+ }
807
+ }
808
+ }
809
+ let s0 = swapBytes(counter0) ^ roundKeys[0];
810
+ let s1 = swapBytes(counter1) ^ roundKeys[1];
811
+ let s2 = swapBytes(counter2) ^ roundKeys[2];
812
+ let s3 = swapBytes(counter3) ^ roundKeys[3];
813
+ let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
814
+ let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
815
+ let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
816
+ let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
817
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
818
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
819
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
820
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
821
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
822
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
823
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
824
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
825
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
826
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
827
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
828
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
829
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
830
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
831
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
832
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
833
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
834
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
835
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
836
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
837
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
838
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
839
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
840
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
841
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
842
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
843
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
844
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
845
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
846
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
847
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
848
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
849
+ let indexKey = 40;
850
+ if (rounds > 10) {
851
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
852
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
853
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
854
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
855
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
856
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
857
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
858
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
859
+ indexKey = 48;
860
+ }
861
+ if (rounds > 12) {
862
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
863
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
864
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
865
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
866
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
867
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
868
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
869
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
870
+ indexKey = 56;
871
+ }
872
+ keystream[0] = ((S_BOX[t0 >>> 24] << 24) | (S_BOX[(t1 >>> 16) & 255] << 16) | (S_BOX[(t2 >>> 8) & 255] << 8) | S_BOX[t3 & 255]) ^ roundKeys[indexKey];
873
+ keystream[1] = ((S_BOX[t1 >>> 24] << 24) | (S_BOX[(t2 >>> 16) & 255] << 16) | (S_BOX[(t3 >>> 8) & 255] << 8) | S_BOX[t0 & 255]) ^ roundKeys[indexKey + 1];
874
+ keystream[2] = ((S_BOX[t2 >>> 24] << 24) | (S_BOX[(t3 >>> 16) & 255] << 16) | (S_BOX[(t0 >>> 8) & 255] << 8) | S_BOX[t1 & 255]) ^ roundKeys[indexKey + 2];
875
+ keystream[3] = ((S_BOX[t3 >>> 24] << 24) | (S_BOX[(t0 >>> 16) & 255] << 16) | (S_BOX[(t1 >>> 8) & 255] << 8) | S_BOX[t2 & 255]) ^ roundKeys[indexKey + 3];
821
876
  }
822
877
  }
823
878
 
@@ -941,47 +996,126 @@
941
996
  for (let index = 0; index < 16; index++) {
942
997
  schedule[index] = view.getInt32(offset + 4 * index);
943
998
  }
944
- for (let index = 16; index < SHA1_SCHEDULE_LENGTH; index++) {
945
- const word = schedule[index - 3] ^ schedule[index - 8] ^ schedule[index - 14] ^ schedule[index - 16];
946
- schedule[index] = (word << 1) | (word >>> 31);
947
- }
948
999
  let a = state[0];
949
1000
  let b = state[1];
950
1001
  let c = state[2];
951
1002
  let d = state[3];
952
1003
  let e = state[4];
953
1004
  let t;
954
- for (let index = 0; index < 20; index++) {
955
- t = (((a << 5) | (a >>> 27)) + ((b & c) | (~b & d)) + e + 0x5A827999 + schedule[index]) | 0;
956
- e = d;
957
- d = c;
958
- c = (b << 30) | (b >>> 2);
959
- b = a;
960
- a = t;
961
- }
962
- for (let index = 20; index < 40; index++) {
963
- t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + schedule[index]) | 0;
964
- e = d;
965
- d = c;
966
- c = (b << 30) | (b >>> 2);
967
- b = a;
968
- a = t;
969
- }
970
- for (let index = 40; index < 60; index++) {
971
- t = (((a << 5) | (a >>> 27)) + ((b & c) | (b & d) | (c & d)) + e + 0x8F1BBCDC + schedule[index]) | 0;
972
- e = d;
973
- d = c;
974
- c = (b << 30) | (b >>> 2);
975
- b = a;
976
- a = t;
977
- }
978
- for (let index = 60; index < SHA1_SCHEDULE_LENGTH; index++) {
979
- t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + schedule[index]) | 0;
980
- e = d;
981
- d = c;
982
- c = (b << 30) | (b >>> 2);
983
- b = a;
984
- a = t;
1005
+ for (let index = 0; index < 15; index += 5) {
1006
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
1007
+ b = (b << 30) | (b >>> 2);
1008
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
1009
+ a = (a << 30) | (a >>> 2);
1010
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
1011
+ e = (e << 30) | (e >>> 2);
1012
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
1013
+ d = (d << 30) | (d >>> 2);
1014
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
1015
+ c = (c << 30) | (c >>> 2);
1016
+ }
1017
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
1018
+ b = (b << 30) | (b >>> 2);
1019
+ t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
1020
+ t = (t << 1) | (t >>> 31);
1021
+ schedule[0] = t;
1022
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
1023
+ a = (a << 30) | (a >>> 2);
1024
+ t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
1025
+ t = (t << 1) | (t >>> 31);
1026
+ schedule[1] = t;
1027
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
1028
+ e = (e << 30) | (e >>> 2);
1029
+ t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
1030
+ t = (t << 1) | (t >>> 31);
1031
+ schedule[2] = t;
1032
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
1033
+ d = (d << 30) | (d >>> 2);
1034
+ t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
1035
+ t = (t << 1) | (t >>> 31);
1036
+ schedule[3] = t;
1037
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
1038
+ c = (c << 30) | (c >>> 2);
1039
+ for (let index = 20; index < 40; index += 5) {
1040
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
1041
+ t = (t << 1) | (t >>> 31);
1042
+ schedule[(index) & 15] = t;
1043
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
1044
+ b = (b << 30) | (b >>> 2);
1045
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
1046
+ t = (t << 1) | (t >>> 31);
1047
+ schedule[(index + 1) & 15] = t;
1048
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
1049
+ a = (a << 30) | (a >>> 2);
1050
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
1051
+ t = (t << 1) | (t >>> 31);
1052
+ schedule[(index + 2) & 15] = t;
1053
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
1054
+ e = (e << 30) | (e >>> 2);
1055
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
1056
+ t = (t << 1) | (t >>> 31);
1057
+ schedule[(index + 3) & 15] = t;
1058
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
1059
+ d = (d << 30) | (d >>> 2);
1060
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
1061
+ t = (t << 1) | (t >>> 31);
1062
+ schedule[(index + 4) & 15] = t;
1063
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
1064
+ c = (c << 30) | (c >>> 2);
1065
+ }
1066
+ for (let index = 40; index < 60; index += 5) {
1067
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
1068
+ t = (t << 1) | (t >>> 31);
1069
+ schedule[(index) & 15] = t;
1070
+ e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
1071
+ b = (b << 30) | (b >>> 2);
1072
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
1073
+ t = (t << 1) | (t >>> 31);
1074
+ schedule[(index + 1) & 15] = t;
1075
+ d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
1076
+ a = (a << 30) | (a >>> 2);
1077
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
1078
+ t = (t << 1) | (t >>> 31);
1079
+ schedule[(index + 2) & 15] = t;
1080
+ c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
1081
+ e = (e << 30) | (e >>> 2);
1082
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
1083
+ t = (t << 1) | (t >>> 31);
1084
+ schedule[(index + 3) & 15] = t;
1085
+ b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
1086
+ d = (d << 30) | (d >>> 2);
1087
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
1088
+ t = (t << 1) | (t >>> 31);
1089
+ schedule[(index + 4) & 15] = t;
1090
+ a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
1091
+ c = (c << 30) | (c >>> 2);
1092
+ }
1093
+ for (let index = 60; index < 80; index += 5) {
1094
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
1095
+ t = (t << 1) | (t >>> 31);
1096
+ schedule[(index) & 15] = t;
1097
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
1098
+ b = (b << 30) | (b >>> 2);
1099
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
1100
+ t = (t << 1) | (t >>> 31);
1101
+ schedule[(index + 1) & 15] = t;
1102
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
1103
+ a = (a << 30) | (a >>> 2);
1104
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
1105
+ t = (t << 1) | (t >>> 31);
1106
+ schedule[(index + 2) & 15] = t;
1107
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
1108
+ e = (e << 30) | (e >>> 2);
1109
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
1110
+ t = (t << 1) | (t >>> 31);
1111
+ schedule[(index + 3) & 15] = t;
1112
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
1113
+ d = (d << 30) | (d >>> 2);
1114
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
1115
+ t = (t << 1) | (t >>> 31);
1116
+ schedule[(index + 4) & 15] = t;
1117
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
1118
+ c = (c << 30) | (c >>> 2);
985
1119
  }
986
1120
  state[0] = (state[0] + a) | 0;
987
1121
  state[1] = (state[1] + b) | 0;
@@ -1044,6 +1178,10 @@
1044
1178
  return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
1045
1179
  }
1046
1180
 
1181
+ function swapBytes(value) {
1182
+ return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
1183
+ }
1184
+
1047
1185
  function multiplyByTwo(value) {
1048
1186
  return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
1049
1187
  }
@@ -1731,8 +1869,8 @@
1731
1869
  let crc32Stream, encryptionStream, gzipCrc32Stream;
1732
1870
  let readable = super.readable;
1733
1871
  const codecStreams = format && getCodecStreams(format);
1734
- const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
1735
- Boolean(useCompressionStream && CompressionStream);
1872
+ const GzipCompressionStream = getGzipCompressionStream(useCompressionStream, CompressionStream, CompressionStreamFallback);
1873
+ const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) && Boolean(GzipCompressionStream);
1736
1874
  if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
1737
1875
  crc32Stream = new Crc32Stream();
1738
1876
  readable = pipeThrough(readable, crc32Stream);
@@ -1742,7 +1880,7 @@
1742
1880
  readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod, uncompressedSize: inputSize }));
1743
1881
  } else if (useGzipCrc32) {
1744
1882
  gzipCrc32Stream = new GzipToRawDeflateStream();
1745
- readable = pipeThroughBackpressured(readable, new CompressionStream(FORMAT_GZIP));
1883
+ readable = pipeThroughBackpressured(readable, new GzipCompressionStream(FORMAT_GZIP, { level, chunkSize }));
1746
1884
  readable = pipeThrough(readable, gzipCrc32Stream);
1747
1885
  } else {
1748
1886
  try {
@@ -1816,8 +1954,7 @@
1816
1954
  }
1817
1955
  }
1818
1956
 
1819
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
1820
- const crc32 = new Crc32();
1957
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
1821
1958
  let outputLength = 0;
1822
1959
  let inputDone = false;
1823
1960
  let watchdogTimeout;
@@ -1891,7 +2028,7 @@
1891
2028
  constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
1892
2029
  super({});
1893
2030
  const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
1894
- let crc32Stream, decryptionStream;
2031
+ let crc32Stream, decryptionStream, gzipCrc32;
1895
2032
  let readable = super.readable;
1896
2033
  if (encrypted) {
1897
2034
  if (zipCrypto) {
@@ -1918,19 +2055,20 @@
1918
2055
  } catch {
1919
2056
  throw error;
1920
2057
  }
1921
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize);
2058
+ gzipCrc32 = new Crc32();
2059
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, gzipCrc32);
1922
2060
  }
1923
2061
  }
1924
2062
  readable = mapInflateStreamError(readable);
1925
2063
  }
1926
- if (checkCrc32) {
2064
+ if (checkCrc32 && !gzipCrc32) {
1927
2065
  crc32Stream = new Crc32Stream();
1928
2066
  readable = pipeThrough(readable, crc32Stream);
1929
2067
  }
1930
2068
  setReadable(this, readable, () => {
1931
2069
  if (checkCrc32) {
1932
- const computedCrc32View = new DataView(crc32Stream.value.buffer);
1933
- if (crc32 != computedCrc32View.getUint32(0, false)) {
2070
+ const computedCrc32 = gzipCrc32 ? gzipCrc32.get() >>> 0 : new DataView(crc32Stream.value.buffer).getUint32(0, false);
2071
+ if (crc32 != computedCrc32) {
1934
2072
  throw new Error(ERR_INVALID_CRC32);
1935
2073
  }
1936
2074
  }
@@ -1986,6 +2124,14 @@
1986
2124
  return new CodecStreamClass(format, options);
1987
2125
  }
1988
2126
 
2127
+ function getGzipCompressionStream(useCompressionStream, CompressionStreamNative, CompressionStreamFallback) {
2128
+ if (useCompressionStream && CompressionStreamNative) {
2129
+ return CompressionStreamNative;
2130
+ } else if (CompressionStreamFallback && CompressionStreamFallback.requiresModule) {
2131
+ return CompressionStreamFallback;
2132
+ }
2133
+ }
2134
+
1989
2135
  function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
1990
2136
  const Stream = useCompressionStream && CompressionStreamNative ?
1991
2137
  CompressionStreamNative :
@@ -2333,7 +2479,8 @@
2333
2479
  return new Promise(resolve => {
2334
2480
  const { worker, busy } = workerData;
2335
2481
  if (busy) {
2336
- workerData.resolveTerminated = resolve;
2482
+ workerData.terminateResolvers = workerData.terminateResolvers || [];
2483
+ workerData.terminateResolvers.push(resolve);
2337
2484
  } else {
2338
2485
  if (worker) {
2339
2486
  worker.terminate();
@@ -2346,17 +2493,19 @@
2346
2493
  },
2347
2494
  onTaskFinished() {
2348
2495
  if (workerData.busy) {
2349
- const { resolveTerminated, worker } = workerData;
2350
- if (resolveTerminated) {
2351
- workerData.resolveTerminated = null;
2496
+ const { terminateResolvers, worker } = workerData;
2497
+ if (terminateResolvers) {
2498
+ workerData.terminateResolvers = null;
2352
2499
  if (worker) {
2353
2500
  workerData.terminated = true;
2354
2501
  worker.terminate();
2355
2502
  }
2356
- resolveTerminated();
2357
2503
  }
2358
2504
  workerData.busy = false;
2359
- onTaskFinished(workerData);
2505
+ const pendingTasks = onTaskFinished(workerData);
2506
+ if (terminateResolvers) {
2507
+ terminateResolvers.forEach(resolve => resolve(pendingTasks));
2508
+ }
2360
2509
  }
2361
2510
  }
2362
2511
  });
@@ -3041,7 +3190,10 @@
3041
3190
 
3042
3191
  function onTaskFinished(workerData) {
3043
3192
  clearStarvationTimeout();
3044
- if (pendingRequests.length) {
3193
+ if (workerData.terminated) {
3194
+ workerData.terminated = false;
3195
+ return runPendingRequestsInline();
3196
+ } else if (pendingRequests.length) {
3045
3197
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
3046
3198
  resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
3047
3199
  armStarvationTimeout();
@@ -3079,12 +3231,26 @@
3079
3231
  starvationTimeout = null;
3080
3232
  if (pendingRequests.length) {
3081
3233
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
3082
- const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
3083
- resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
3234
+ resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), onInlineTaskFinished));
3084
3235
  armStarvationTimeout();
3085
3236
  }
3086
3237
  }
3087
3238
 
3239
+ function runPendingRequestsInline() {
3240
+ const tasks = pendingRequests.splice(0).map(({ resolve, stream, workerOptions }) => new Promise(resolveTask => {
3241
+ resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), () => {
3242
+ onInlineTaskFinished();
3243
+ resolveTask();
3244
+ }));
3245
+ }));
3246
+ clearStarvationTimeout();
3247
+ return Promise.all(tasks);
3248
+ }
3249
+
3250
+ function getInlineWorkerOptions(workerOptions) {
3251
+ return Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
3252
+ }
3253
+
3088
3254
  function onInlineTaskFinished() {
3089
3255
  clearStarvationTimeout();
3090
3256
  armStarvationTimeout();
@@ -3094,18 +3260,14 @@
3094
3260
  const { config } = workerOptions;
3095
3261
  const { terminateWorkerTimeout } = config;
3096
3262
  if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
3097
- if (workerData.terminated) {
3098
- workerData.terminated = false;
3099
- } else {
3100
- workerData.terminateTimeout = setTimeout(async () => {
3101
- pool = pool.filter(data => data != workerData);
3102
- try {
3103
- await workerData.terminate();
3104
- } catch {
3105
- // ignored
3106
- }
3107
- }, terminateWorkerTimeout);
3108
- }
3263
+ workerData.terminateTimeout = setTimeout(async () => {
3264
+ pool = pool.filter(data => data != workerData);
3265
+ try {
3266
+ await workerData.terminate();
3267
+ } catch {
3268
+ // ignored
3269
+ }
3270
+ }, terminateWorkerTimeout);
3109
3271
  }
3110
3272
  }
3111
3273
 
@@ -3118,10 +3280,13 @@
3118
3280
  }
3119
3281
 
3120
3282
  async function terminateWorkers() {
3121
- await Promise.allSettled(pool.map(workerData => {
3122
- clearTerminateTimeout(workerData);
3123
- return workerData.terminate();
3124
- }));
3283
+ await Promise.allSettled([
3284
+ runPendingRequestsInline(),
3285
+ ...pool.map(workerData => {
3286
+ clearTerminateTimeout(workerData);
3287
+ return workerData.terminate();
3288
+ })
3289
+ ]);
3125
3290
  resetWebWorkerSupport();
3126
3291
  }
3127
3292
 
@@ -3196,6 +3361,19 @@
3196
3361
  return decode(value, encoding, true);
3197
3362
  }
3198
3363
 
3364
+ function isUTF8Text(value) {
3365
+ if (value.some(byte => byte > 0x7f)) {
3366
+ try {
3367
+ new TextDecoder("utf-8", { fatal: true }).decode(value);
3368
+ return true;
3369
+ } catch {
3370
+ return false;
3371
+ }
3372
+ } else {
3373
+ return false;
3374
+ }
3375
+ }
3376
+
3199
3377
  function decodeTextRemovingBOM(value, encoding) {
3200
3378
  return decode(value, encoding, false);
3201
3379
  }
@@ -4485,6 +4663,7 @@
4485
4663
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
4486
4664
  const MAX_KNOWN_VERSION = 63;
4487
4665
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4666
+ const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
4488
4667
  const CHARSET_UTF8 = "utf-8";
4489
4668
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4490
4669
  const CHARSET_CP437 = "cp437";
@@ -4519,7 +4698,7 @@
4519
4698
  Object.assign(this, {
4520
4699
  reader: new GenericReader(reader),
4521
4700
  options,
4522
- readRanges: new Map()
4701
+ readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
4523
4702
  });
4524
4703
  }
4525
4704
 
@@ -4737,12 +4916,13 @@
4737
4916
  const versionMadeBy = getUint16$1(directoryView, offset + 4);
4738
4917
  const msDosCompatible = versionMadeBy >> 8 == 0;
4739
4918
  const unixCompatible = versionMadeBy >> 8 == 3;
4740
- const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
4741
4919
  const commentLength = getUint16$1(directoryView, offset + 32);
4742
4920
  const endOffset = commentOffset + commentLength;
4743
- const rawComment = directoryArray.subarray(commentOffset, endOffset);
4744
- const filenameUTF8 = languageEncodingFlag;
4745
- const commentUTF8 = languageEncodingFlag;
4921
+ const rawEntryData = new Uint8Array(directoryArray.subarray(filenameOffset, endOffset));
4922
+ const rawFilename = rawEntryData.subarray(0, fileEntry.filenameLength);
4923
+ const rawComment = rawEntryData.subarray(fileEntry.filenameLength + fileEntry.extraFieldLength);
4924
+ const filenameUTF8 = languageEncodingFlag || (!filenameEncoding && isUTF8Text(rawFilename));
4925
+ const commentUTF8 = languageEncodingFlag || (!commentEncoding && isUTF8Text(rawComment));
4746
4926
  const externalFileAttributes = getUint32$1(directoryView, offset + 38);
4747
4927
  const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
4748
4928
  const msdosAttributes = {
@@ -4793,7 +4973,7 @@
4793
4973
  rawFilename,
4794
4974
  filenameUTF8,
4795
4975
  commentUTF8,
4796
- rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset),
4976
+ rawExtraField: rawEntryData.subarray(fileEntry.filenameLength, fileEntry.filenameLength + fileEntry.extraFieldLength),
4797
4977
  rawComment,
4798
4978
  filename,
4799
4979
  comment
@@ -5164,7 +5344,6 @@
5164
5344
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5165
5345
  }
5166
5346
  const size = compressedSize;
5167
- const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5168
5347
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5169
5348
  throwIfAborted(signal);
5170
5349
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -5238,6 +5417,7 @@
5238
5417
  writer = new GenericWriter(writer);
5239
5418
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5240
5419
  ({ writable } = writer);
5420
+ const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5241
5421
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5242
5422
  if (writtenSize != outputSize) {
5243
5423
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
@@ -5301,7 +5481,7 @@
5301
5481
  if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
5302
5482
  const signatureDataLength = getUint16$1(signatureRecordView, 4);
5303
5483
  if (6 + signatureDataLength <= signatureRecordArray.length) {
5304
- return signatureRecordArray.subarray(6, 6 + signatureDataLength);
5484
+ return new Uint8Array(signatureRecordArray.subarray(6, 6 + signatureDataLength));
5305
5485
  }
5306
5486
  }
5307
5487
  }
@@ -5673,14 +5853,61 @@
5673
5853
  end: dataOffset + compressedSize + dataDescriptorLength,
5674
5854
  fileEntry
5675
5855
  };
5676
- for (const [otherIndex, otherRange] of readRanges) {
5677
- if (otherIndex != index && range.start < otherRange.end && otherRange.start < range.end) {
5856
+ const { indexes, sortedRanges, pendingRanges } = readRanges;
5857
+ if (!indexes.has(index)) {
5858
+ const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
5859
+ if (overlappingRange) {
5678
5860
  const error = new Error(ERR_OVERLAPPING_ENTRY);
5679
- error.overlappingEntry = otherRange.fileEntry;
5861
+ error.overlappingEntry = overlappingRange.fileEntry;
5680
5862
  throw error;
5681
5863
  }
5864
+ indexes.add(index);
5865
+ pendingRanges.push(range);
5866
+ if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
5867
+ pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
5868
+ readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
5869
+ pendingRanges.length = 0;
5870
+ }
5871
+ }
5872
+ }
5873
+
5874
+ function findOverlappingRange(sortedRanges, range) {
5875
+ let low = 0;
5876
+ let high = sortedRanges.length;
5877
+ while (low < high) {
5878
+ const middle = (low + high) >>> 1;
5879
+ if (sortedRanges[middle].start < range.start) {
5880
+ low = middle + 1;
5881
+ } else {
5882
+ high = middle;
5883
+ }
5884
+ }
5885
+ const previousRange = sortedRanges[low - 1];
5886
+ const nextRange = sortedRanges[low];
5887
+ if (previousRange && rangesOverlap(range, previousRange)) {
5888
+ return previousRange;
5889
+ }
5890
+ if (nextRange && rangesOverlap(range, nextRange)) {
5891
+ return nextRange;
5892
+ }
5893
+ }
5894
+
5895
+ function rangesOverlap(range, otherRange) {
5896
+ return range.start < otherRange.end && otherRange.start < range.end;
5897
+ }
5898
+
5899
+ function mergeRanges(sortedRanges, pendingRanges) {
5900
+ const mergedRanges = [];
5901
+ let indexSorted = 0;
5902
+ let indexPending = 0;
5903
+ while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
5904
+ if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
5905
+ mergedRanges.push(sortedRanges[indexSorted++]);
5906
+ } else {
5907
+ mergedRanges.push(pendingRanges[indexPending++]);
5908
+ }
5682
5909
  }
5683
- readRanges.set(index, range);
5910
+ return mergedRanges;
5684
5911
  }
5685
5912
 
5686
5913
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
@@ -5777,10 +6004,10 @@
5777
6004
  if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
5778
6005
  pathParts.pop();
5779
6006
  }
5780
- if (pathParts.includes("..") || filename.startsWith("/") || filename.startsWith("\\\\") || DRIVE_LETTER_REGEXP.test(filename)) {
6007
+ if (PARENT_DIRECTORY_REGEXP.test(filename) || filename.startsWith("/") || filename.startsWith("\\") || DRIVE_LETTER_REGEXP.test(filename)) {
5781
6008
  return true;
5782
6009
  }
5783
- return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
6010
+ return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes("") || filename.includes("\0"));
5784
6011
  }
5785
6012
 
5786
6013
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
@@ -5866,7 +6093,7 @@
5866
6093
  }
5867
6094
 
5868
6095
  function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
5869
- return { offset, buffer: scanArray.slice(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH).buffer };
6096
+ return { offset, buffer: new Uint8Array(scanArray.subarray(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH)).buffer };
5870
6097
  }
5871
6098
 
5872
6099
  async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
@@ -8513,7 +8740,7 @@
8513
8740
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8514
8741
  */
8515
8742
 
8516
- const VERSION = "2.14.0";
8743
+ const VERSION = "2.15.0";
8517
8744
 
8518
8745
  /*
8519
8746
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.