@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
@@ -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
  }
@@ -4505,6 +4683,7 @@
4505
4683
  const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
4506
4684
  const MAX_KNOWN_VERSION = 63;
4507
4685
  const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
4686
+ const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
4508
4687
  const CHARSET_UTF8 = "utf-8";
4509
4688
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
4510
4689
  const CHARSET_CP437 = "cp437";
@@ -4539,7 +4718,7 @@
4539
4718
  Object.assign(this, {
4540
4719
  reader: new GenericReader(reader),
4541
4720
  options,
4542
- readRanges: new Map()
4721
+ readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
4543
4722
  });
4544
4723
  }
4545
4724
 
@@ -4757,12 +4936,13 @@
4757
4936
  const versionMadeBy = getUint16$1(directoryView, offset + 4);
4758
4937
  const msDosCompatible = versionMadeBy >> 8 == 0;
4759
4938
  const unixCompatible = versionMadeBy >> 8 == 3;
4760
- const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
4761
4939
  const commentLength = getUint16$1(directoryView, offset + 32);
4762
4940
  const endOffset = commentOffset + commentLength;
4763
- const rawComment = directoryArray.subarray(commentOffset, endOffset);
4764
- const filenameUTF8 = languageEncodingFlag;
4765
- const commentUTF8 = languageEncodingFlag;
4941
+ const rawEntryData = new Uint8Array(directoryArray.subarray(filenameOffset, endOffset));
4942
+ const rawFilename = rawEntryData.subarray(0, fileEntry.filenameLength);
4943
+ const rawComment = rawEntryData.subarray(fileEntry.filenameLength + fileEntry.extraFieldLength);
4944
+ const filenameUTF8 = languageEncodingFlag || (!filenameEncoding && isUTF8Text(rawFilename));
4945
+ const commentUTF8 = languageEncodingFlag || (!commentEncoding && isUTF8Text(rawComment));
4766
4946
  const externalFileAttributes = getUint32$1(directoryView, offset + 38);
4767
4947
  const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
4768
4948
  const msdosAttributes = {
@@ -4813,7 +4993,7 @@
4813
4993
  rawFilename,
4814
4994
  filenameUTF8,
4815
4995
  commentUTF8,
4816
- rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset),
4996
+ rawExtraField: rawEntryData.subarray(fileEntry.filenameLength, fileEntry.filenameLength + fileEntry.extraFieldLength),
4817
4997
  rawComment,
4818
4998
  filename,
4819
4999
  comment
@@ -5184,7 +5364,6 @@
5184
5364
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5185
5365
  }
5186
5366
  const size = compressedSize;
5187
- const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5188
5367
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5189
5368
  throwIfAborted(signal);
5190
5369
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -5258,6 +5437,7 @@
5258
5437
  writer = new GenericWriter(writer);
5259
5438
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5260
5439
  ({ writable } = writer);
5440
+ const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5261
5441
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5262
5442
  if (writtenSize != outputSize) {
5263
5443
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
@@ -5321,7 +5501,7 @@
5321
5501
  if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
5322
5502
  const signatureDataLength = getUint16$1(signatureRecordView, 4);
5323
5503
  if (6 + signatureDataLength <= signatureRecordArray.length) {
5324
- return signatureRecordArray.subarray(6, 6 + signatureDataLength);
5504
+ return new Uint8Array(signatureRecordArray.subarray(6, 6 + signatureDataLength));
5325
5505
  }
5326
5506
  }
5327
5507
  }
@@ -5693,14 +5873,61 @@
5693
5873
  end: dataOffset + compressedSize + dataDescriptorLength,
5694
5874
  fileEntry
5695
5875
  };
5696
- for (const [otherIndex, otherRange] of readRanges) {
5697
- if (otherIndex != index && range.start < otherRange.end && otherRange.start < range.end) {
5876
+ const { indexes, sortedRanges, pendingRanges } = readRanges;
5877
+ if (!indexes.has(index)) {
5878
+ const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
5879
+ if (overlappingRange) {
5698
5880
  const error = new Error(ERR_OVERLAPPING_ENTRY);
5699
- error.overlappingEntry = otherRange.fileEntry;
5881
+ error.overlappingEntry = overlappingRange.fileEntry;
5700
5882
  throw error;
5701
5883
  }
5884
+ indexes.add(index);
5885
+ pendingRanges.push(range);
5886
+ if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
5887
+ pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
5888
+ readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
5889
+ pendingRanges.length = 0;
5890
+ }
5891
+ }
5892
+ }
5893
+
5894
+ function findOverlappingRange(sortedRanges, range) {
5895
+ let low = 0;
5896
+ let high = sortedRanges.length;
5897
+ while (low < high) {
5898
+ const middle = (low + high) >>> 1;
5899
+ if (sortedRanges[middle].start < range.start) {
5900
+ low = middle + 1;
5901
+ } else {
5902
+ high = middle;
5903
+ }
5904
+ }
5905
+ const previousRange = sortedRanges[low - 1];
5906
+ const nextRange = sortedRanges[low];
5907
+ if (previousRange && rangesOverlap(range, previousRange)) {
5908
+ return previousRange;
5909
+ }
5910
+ if (nextRange && rangesOverlap(range, nextRange)) {
5911
+ return nextRange;
5912
+ }
5913
+ }
5914
+
5915
+ function rangesOverlap(range, otherRange) {
5916
+ return range.start < otherRange.end && otherRange.start < range.end;
5917
+ }
5918
+
5919
+ function mergeRanges(sortedRanges, pendingRanges) {
5920
+ const mergedRanges = [];
5921
+ let indexSorted = 0;
5922
+ let indexPending = 0;
5923
+ while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
5924
+ if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
5925
+ mergedRanges.push(sortedRanges[indexSorted++]);
5926
+ } else {
5927
+ mergedRanges.push(pendingRanges[indexPending++]);
5928
+ }
5702
5929
  }
5703
- readRanges.set(index, range);
5930
+ return mergedRanges;
5704
5931
  }
5705
5932
 
5706
5933
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
@@ -5797,10 +6024,10 @@
5797
6024
  if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
5798
6025
  pathParts.pop();
5799
6026
  }
5800
- if (pathParts.includes("..") || filename.startsWith("/") || filename.startsWith("\\\\") || DRIVE_LETTER_REGEXP.test(filename)) {
6027
+ if (PARENT_DIRECTORY_REGEXP.test(filename) || filename.startsWith("/") || filename.startsWith("\\") || DRIVE_LETTER_REGEXP.test(filename)) {
5801
6028
  return true;
5802
6029
  }
5803
- return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
6030
+ return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes("") || filename.includes("\0"));
5804
6031
  }
5805
6032
 
5806
6033
  function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
@@ -5886,7 +6113,7 @@
5886
6113
  }
5887
6114
 
5888
6115
  function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
5889
- return { offset, buffer: scanArray.slice(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH).buffer };
6116
+ return { offset, buffer: new Uint8Array(scanArray.subarray(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH)).buffer };
5890
6117
  }
5891
6118
 
5892
6119
  async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
@@ -8631,7 +8858,7 @@
8631
8858
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8632
8859
  */
8633
8860
 
8634
- const VERSION = "2.14.0";
8861
+ const VERSION = "2.15.0";
8635
8862
 
8636
8863
  /*
8637
8864
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.