@zip.js/zip.js 2.13.1 → 2.14.1

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 (51) hide show
  1. package/BENCHMARKS.md +349 -416
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +761 -945
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +626 -911
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +768 -948
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +633 -914
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +768 -948
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +635 -916
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +771 -951
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +628 -913
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-module.wasm +0 -0
  20. package/dist/zip-native.js +628 -913
  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 +764 -948
  25. package/dist/zip.min.js +1 -1
  26. package/index-native.cjs +635 -916
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +771 -951
  29. package/index.d.cts +52 -12
  30. package/index.d.ts +52 -12
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-worker.js +37 -26
  33. package/lib/core/io.js +29 -21
  34. package/lib/core/streams/aes-crypto-stream.js +58 -99
  35. package/lib/core/streams/codecs/aes-hmac-sha1.js +486 -0
  36. package/lib/core/streams/zlib-wasm/aes-hmac-sha1-wasm.js +106 -0
  37. package/lib/core/streams/zlib-wasm/zlib-streams-loader.js +4 -0
  38. package/lib/core/streams/zlib-wasm/zlib-streams.js +2 -7
  39. package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
  40. package/lib/core/version.js +1 -1
  41. package/lib/core/web-worker-base.js +15 -9
  42. package/lib/core/web-worker-inline-native.js +1 -1
  43. package/lib/core/web-worker-inline-wasm.js +1 -1
  44. package/lib/core/web-worker-wasm.js +2 -0
  45. package/lib/core/zip-fs.js +7 -3
  46. package/lib/core/zip-reader.js +53 -6
  47. package/lib/core/zip-writer.js +1 -2
  48. package/lib/core/zlib-streams-inline.js +1 -1
  49. package/lib/zip-module-wasm-base.js +3 -1
  50. package/package.json +1 -1
  51. package/lib/core/streams/codecs/sjcl.js +0 -795
package/dist/zip-core.js CHANGED
@@ -573,7 +573,7 @@
573
573
  T[k][n] = (previous >>> 8) ^ T[0][previous & 0xFF];
574
574
  }
575
575
  }
576
- const [T0, T1, T2, T3, T4, T5, T6, T7] = T;
576
+ const [T0$1, T1$1, T2$1, T3$1, T4, T5, T6, T7] = T;
577
577
 
578
578
  class Crc32 {
579
579
 
@@ -595,12 +595,12 @@
595
595
  const a = crc ^ view.getInt32(offset, true);
596
596
  const b = view.getInt32(offset + 4, true);
597
597
  crc = T7[a & 0xFF] ^ T6[(a >>> 8) & 0xFF] ^ T5[(a >>> 16) & 0xFF] ^ T4[(a >>> 24) & 0xFF] ^
598
- T3[b & 0xFF] ^ T2[(b >>> 8) & 0xFF] ^ T1[(b >>> 16) & 0xFF] ^ T0[(b >>> 24) & 0xFF];
598
+ T3$1[b & 0xFF] ^ T2$1[(b >>> 8) & 0xFF] ^ T1$1[(b >>> 16) & 0xFF] ^ T0$1[(b >>> 24) & 0xFF];
599
599
  }
600
600
  }
601
601
  // Remaining tail (and non-typed inputs) byte-at-a-time with the base table.
602
602
  for (; offset < length; offset++) {
603
- crc = (crc >>> 8) ^ T0[(crc ^ data[offset]) & 0xFF];
603
+ crc = (crc >>> 8) ^ T0$1[(crc ^ data[offset]) & 0xFF];
604
604
  }
605
605
  this.crc = crc;
606
606
  }
@@ -704,794 +704,487 @@
704
704
  }
705
705
  }
706
706
 
707
- // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
708
-
709
- // deno-lint-ignore-file no-this-alias
710
-
711
707
  /*
712
- * SJCL is open. You can use, modify and redistribute it under a BSD
713
- * license or under the GNU GPL, version 2.0.
714
- */
715
-
716
- /** @fileOverview Javascript cryptography implementation.
717
- *
718
- * Crush to remove comments, shorten variable names and
719
- * generally reduce transmission size.
720
- *
721
- * @author Emily Stark
722
- * @author Mike Hamburg
723
- * @author Dan Boneh
724
- */
725
-
726
- /*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
727
-
728
- /** @fileOverview Arrays of bits, encoded as arrays of Numbers.
729
- *
730
- * @author Emily Stark
731
- * @author Mike Hamburg
732
- * @author Dan Boneh
733
- */
734
-
735
- /**
736
- * Arrays of bits, encoded as arrays of Numbers.
737
- * @namespace
738
- * @description
739
- * <p>
740
- * These objects are the currency accepted by SJCL's crypto functions.
741
- * </p>
742
- *
743
- * <p>
744
- * Most of our crypto primitives operate on arrays of 4-byte words internally,
745
- * but many of them can take arguments that are not a multiple of 4 bytes.
746
- * This library encodes arrays of bits (whose size need not be a multiple of 8
747
- * bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
748
- * array of words, 32 bits at a time. Since the words are double-precision
749
- * floating point numbers, they fit some extra data. We use this (in a private,
750
- * possibly-changing manner) to encode the number of bits actually present
751
- * in the last word of the array.
752
- * </p>
753
- *
754
- * <p>
755
- * Because bitwise ops clear this out-of-band data, these arrays can be passed
756
- * to ciphers like AES which want arrays of words.
757
- * </p>
758
- */
759
- const bitArray = {
760
- /**
761
- * Concatenate two bit arrays.
762
- * @param {bitArray} a1 The first array.
763
- * @param {bitArray} a2 The second array.
764
- * @return {bitArray} The concatenation of a1 and a2.
765
- */
766
- concat(a1, a2) {
767
- if (a1.length === 0 || a2.length === 0) {
768
- return a1.concat(a2);
769
- }
770
-
771
- const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
772
- if (shift === 32) {
773
- return a1.concat(a2);
774
- } else {
775
- return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
776
- }
777
- },
778
-
779
- /**
780
- * Find the length of an array of bits.
781
- * @param {bitArray} a The array.
782
- * @return {Number} The length of a, in bits.
783
- */
784
- bitLength(a) {
785
- const l = a.length;
786
- if (l === 0) {
787
- return 0;
788
- }
789
- const x = a[l - 1];
790
- return (l - 1) * 32 + bitArray.getPartial(x);
791
- },
792
-
793
- /**
794
- * Truncate an array.
795
- * @param {bitArray} a The array.
796
- * @param {Number} len The length to truncate to, in bits.
797
- * @return {bitArray} A new array, truncated to len bits.
798
- */
799
- clamp(a, len) {
800
- if (a.length * 32 < len) {
801
- return a;
802
- }
803
- a = a.slice(0, Math.ceil(len / 32));
804
- const l = a.length;
805
- len = len & 31;
806
- if (l > 0 && len) {
807
- a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
808
- }
809
- return a;
810
- },
811
-
812
- /**
813
- * Make a partial word for a bit array.
814
- * @param {Number} len The number of bits in the word.
815
- * @param {Number} x The bits.
816
- * @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
817
- * @return {Number} The partial word.
818
- */
819
- partial(len, x, _end) {
820
- if (len === 32) {
821
- return x;
822
- }
823
- return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
824
- },
708
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
825
709
 
826
- /**
827
- * Get the number of bits used by a partial word.
828
- * @param {Number} x The partial word.
829
- * @return {Number} The number of bits used by the partial word.
830
- */
831
- getPartial(x) {
832
- return Math.round(x / 0x10000000000) || 32;
833
- },
710
+ Redistribution and use in source and binary forms, with or without
711
+ modification, are permitted provided that the following conditions are met:
834
712
 
835
- /** Shift an array right.
836
- * @param {bitArray} a The array to shift.
837
- * @param {Number} shift The number of bits to shift.
838
- * @param {Number} [carry=0] A byte to carry in
839
- * @param {bitArray} [out=[]] An array to prepend to the output.
840
- * @private
841
- */
842
- _shiftRight(a, shift, carry, out) {
843
- if (out === undefined) {
844
- out = [];
845
- }
713
+ 1. Redistributions of source code must retain the above copyright notice,
714
+ this list of conditions and the following disclaimer.
846
715
 
847
- for (; shift >= 32; shift -= 32) {
848
- out.push(carry);
849
- carry = 0;
850
- }
851
- if (shift === 0) {
852
- return out.concat(a);
853
- }
716
+ 2. Redistributions in binary form must reproduce the above copyright
717
+ notice, this list of conditions and the following disclaimer in
718
+ the documentation and/or other materials provided with the distribution.
854
719
 
855
- for (let i = 0; i < a.length; i++) {
856
- out.push(carry | a[i] >>> shift);
857
- carry = a[i] << (32 - shift);
858
- }
859
- const last2 = a.length ? a[a.length - 1] : 0;
860
- const shift2 = bitArray.getPartial(last2);
861
- out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
862
- return out;
863
- }
864
- };
720
+ 3. The names of the authors may not be used to endorse or promote products
721
+ derived from this software without specific prior written permission.
865
722
 
866
- /** @fileOverview Bit array codec implementations.
867
- *
868
- * @author Emily Stark
869
- * @author Mike Hamburg
870
- * @author Dan Boneh
723
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
724
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
725
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
726
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
727
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
728
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
729
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
730
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
731
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
732
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
871
733
  */
872
734
 
873
- /**
874
- * Arrays of bytes
875
- * @namespace
876
- */
877
- const codec = {
878
- bytes: {
879
- /** Convert from a bitArray to an array of bytes. */
880
- fromBits(arr) {
881
- const bl = bitArray.bitLength(arr);
882
- const byteLength = bl / 8;
883
- const out = new Uint8Array(byteLength);
884
- let tmp;
885
- for (let i = 0; i < byteLength; i++) {
886
- if ((i & 3) === 0) {
887
- tmp = arr[i / 4];
888
- }
889
- out[i] = tmp >>> 24;
890
- tmp <<= 8;
891
- }
892
- return out;
893
- },
894
- /** Convert from an array of bytes to a bitArray. */
895
- toBits(bytes) {
896
- const out = [];
897
- let i;
898
- let tmp = 0;
899
- for (i = 0; i < bytes.length; i++) {
900
- tmp = tmp << 8 | bytes[i];
901
- if ((i & 3) === 3) {
902
- out.push(tmp);
903
- tmp = 0;
904
- }
735
+ const BLOCK_LENGTH$1 = 16;
736
+ const ROUND_KEYS_LENGTH = 60;
737
+ const SHA1_BLOCK_LENGTH = 64;
738
+ const SHA1_DIGEST_LENGTH = 20;
739
+ const SHA1_SCHEDULE_LENGTH = 16;
740
+ const SHA1_LENGTH_OFFSET = 56;
741
+ const SHA1_PADDING = new Uint8Array([0x80]);
742
+ const SHA1_ZERO = new Uint8Array(1);
743
+ const SHA1_INITIAL_STATE = new Int32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
744
+ const HMAC_INNER_PADDING = 0x36;
745
+ const HMAC_OUTER_PADDING = 0x5c;
746
+ const S_BOX = new Uint8Array(256);
747
+ const T0 = new Int32Array(256);
748
+ const T1 = new Int32Array(256);
749
+ const T2 = new Int32Array(256);
750
+ const T3 = new Int32Array(256);
751
+
752
+ let tablesInitialized = false;
753
+
754
+ function createEngine$1(key, authenticationKey) {
755
+ initTables();
756
+ const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
757
+ const rounds = expandKey(key, roundKeys);
758
+ const keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
759
+ const hmac = createHmac(authenticationKey);
760
+ let counter0 = 0;
761
+ let counter1 = 0;
762
+ let counter2 = 0;
763
+ let counter3 = 0;
764
+ return {
765
+ process(data, decrypt) {
766
+ if (decrypt) {
767
+ hmac.update(data, 0, data.length);
905
768
  }
906
- if (i & 3) {
907
- out.push(bitArray.partial(8 * (i & 3), tmp));
769
+ encrypt(data);
770
+ if (!decrypt) {
771
+ hmac.update(data, 0, data.length);
908
772
  }
909
- return out;
773
+ },
774
+ digest() {
775
+ return hmac.digest();
910
776
  }
911
- }
912
- };
913
-
914
- const hash = {};
915
-
916
- /**
917
- * Context for a SHA-1 operation in progress.
918
- * @constructor
919
- */
920
- hash.sha1 = class {
921
- constructor(hash) {
922
- const sha1 = this;
923
- /**
924
- * The hash's block size, in bits.
925
- * @constant
926
- */
927
- sha1.blockSize = 512;
928
- /**
929
- * The SHA-1 initialization vector.
930
- * @private
931
- */
932
- sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
933
- /**
934
- * The SHA-1 hash key.
935
- * @private
936
- */
937
- sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
938
- if (hash) {
939
- sha1._h = hash._h.slice(0);
940
- sha1._buffer = hash._buffer.slice(0);
941
- sha1._length = hash._length;
942
- } else {
943
- sha1.reset();
944
- }
945
- }
946
-
947
- /**
948
- * Reset the hash state.
949
- * @return this
950
- */
951
- reset() {
952
- const sha1 = this;
953
- sha1._h = sha1._init.slice(0);
954
- sha1._buffer = [];
955
- sha1._length = 0;
956
- return sha1;
957
- }
958
-
959
- /**
960
- * Input several words to the hash.
961
- * @param {bitArray|String} data the data to hash.
962
- * @return this
963
- */
964
- update(data) {
965
- const sha1 = this;
966
- if (typeof data === "string") {
967
- data = codec.utf8String.toBits(data);
968
- }
969
- const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
970
- const ol = sha1._length;
971
- const nl = sha1._length = ol + bitArray.bitLength(data);
972
- if (nl > 9007199254740991) {
973
- throw new Error("Cannot hash more than 2^53 - 1 bits");
974
- }
975
- const c = new Uint32Array(b);
976
- let j = 0;
977
- for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
978
- i += sha1.blockSize) {
979
- sha1._block(c.subarray(16 * j, 16 * (j + 1)));
980
- j += 1;
981
- }
982
- b.splice(0, 16 * j);
983
- return sha1;
984
- }
985
-
986
- /**
987
- * Complete hashing and output the hash value.
988
- * @return {bitArray} The hash value, an array of 5 big-endian words. TODO
989
- */
990
- finalize() {
991
- const sha1 = this;
992
- let b = sha1._buffer;
993
- const h = sha1._h;
994
-
995
- // Round out and push the buffer
996
- b = bitArray.concat(b, [bitArray.partial(1, 1)]);
997
- // Round out the buffer to a multiple of 16 words, less the 2 length words.
998
- for (let i = b.length + 2; i & 15; i++) {
999
- b.push(0);
1000
- }
1001
-
1002
- // append the length
1003
- b.push(Math.floor(sha1._length / 0x100000000));
1004
- b.push(sha1._length | 0);
1005
-
1006
- while (b.length) {
1007
- sha1._block(b.splice(0, 16));
1008
- }
1009
-
1010
- sha1.reset();
1011
- return h;
1012
- }
1013
-
1014
- /**
1015
- * The SHA-1 logical functions f(0), f(1), ..., f(79).
1016
- * @private
1017
- */
1018
- _f(t, b, c, d) {
1019
- if (t <= 19) {
1020
- return (b & c) | (~b & d);
1021
- } else if (t <= 39) {
1022
- return b ^ c ^ d;
1023
- } else if (t <= 59) {
1024
- return (b & c) | (b & d) | (c & d);
1025
- } else if (t <= 79) {
1026
- return b ^ c ^ d;
1027
- }
1028
- }
1029
-
1030
- /**
1031
- * Circular left-shift operator.
1032
- * @private
1033
- */
1034
- _S(n, x) {
1035
- return (x << n) | (x >>> 32 - n);
1036
- }
1037
-
1038
- /**
1039
- * Perform one cycle of SHA-1.
1040
- * @param {Uint32Array|bitArray} words one block of words.
1041
- * @private
1042
- */
1043
- _block(words) {
1044
- const sha1 = this;
1045
- const h = sha1._h;
1046
- // When words is passed to _block, it has 16 elements. SHA1 _block
1047
- // function extends words with new elements (at the end there are 80 elements).
1048
- // The problem is that if we use Uint32Array instead of Array,
1049
- // the length of Uint32Array cannot be changed. Thus, we replace words with a
1050
- // normal Array here.
1051
- const w = Array(80); // do not use Uint32Array here as the instantiation is slower
1052
- for (let j = 0; j < 16; j++) {
1053
- w[j] = words[j];
1054
- }
1055
-
1056
- let a = h[0];
1057
- let b = h[1];
1058
- let c = h[2];
1059
- let d = h[3];
1060
- let e = h[4];
1061
-
1062
- for (let t = 0; t <= 79; t++) {
1063
- if (t >= 16) {
1064
- w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
1065
- }
1066
- const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
1067
- sha1._key[Math.floor(t / 20)]) | 0;
1068
- e = d;
1069
- d = c;
1070
- c = sha1._S(30, b);
1071
- b = a;
1072
- a = tmp;
1073
- }
1074
-
1075
- h[0] = (h[0] + a) | 0;
1076
- h[1] = (h[1] + b) | 0;
1077
- h[2] = (h[2] + c) | 0;
1078
- h[3] = (h[3] + d) | 0;
1079
- h[4] = (h[4] + e) | 0;
1080
- }
1081
- };
1082
-
1083
- /** @fileOverview Low-level AES implementation.
1084
- *
1085
- * This file contains a low-level implementation of AES, optimized for
1086
- * size and for efficiency on several browsers. It is based on
1087
- * OpenSSL's aes_core.c, a public-domain implementation by Vincent
1088
- * Rijmen, Antoon Bosselaers and Paulo Barreto.
1089
- *
1090
- * An older version of this implementation is available in the public
1091
- * domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
1092
- * Stanford University 2008-2010 and BSD-licensed for liability
1093
- * reasons.
1094
- *
1095
- * @author Emily Stark
1096
- * @author Mike Hamburg
1097
- * @author Dan Boneh
1098
- */
1099
-
1100
- const cipher = {};
1101
-
1102
- /**
1103
- * Schedule out an AES key for both encryption and decryption. This
1104
- * is a low-level class. Use a cipher mode to do bulk encryption.
1105
- *
1106
- * @constructor
1107
- * @param {Array} key The key as an array of 4, 6 or 8 words.
1108
- */
1109
- cipher.aes = class {
1110
- constructor(key) {
1111
- /**
1112
- * The expanded S-box and inverse S-box tables. These will be computed
1113
- * on the client so that we don't have to send them down the wire.
1114
- *
1115
- * There are two tables, _tables[0] is for encryption and
1116
- * _tables[1] is for decryption.
1117
- *
1118
- * The first 4 sub-tables are the expanded S-box with MixColumns. The
1119
- * last (_tables[01][4]) is the S-box itself.
1120
- *
1121
- * @private
1122
- */
1123
- const aes = this;
1124
- aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
1125
-
1126
- if (!aes._tables[0][0][0]) {
1127
- aes._precompute();
1128
- }
1129
-
1130
- const sbox = aes._tables[0][4];
1131
- const decTable = aes._tables[1];
1132
- const keyLen = key.length;
1133
-
1134
- let i, encKey, decKey, rcon = 1;
1135
-
1136
- if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
1137
- throw new Error("invalid aes key size");
1138
- }
1139
-
1140
- aes._key = [encKey = key.slice(0), decKey = []];
1141
-
1142
- // schedule encryption keys
1143
- for (i = keyLen; i < 4 * keyLen + 28; i++) {
1144
- let tmp = encKey[i - 1];
1145
-
1146
- // apply sbox
1147
- if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
1148
- tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
1149
-
1150
- // shift rows and add rcon
1151
- if (i % keyLen === 0) {
1152
- tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
1153
- rcon = rcon << 1 ^ (rcon >> 7) * 283;
1154
- }
1155
- }
777
+ };
1156
778
 
1157
- encKey[i] = encKey[i - keyLen] ^ tmp;
779
+ function encrypt(data) {
780
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
781
+ const length = data.length;
782
+ let offset = 0;
783
+ for (; offset + BLOCK_LENGTH$1 <= length; offset += BLOCK_LENGTH$1) {
784
+ nextKeystream();
785
+ view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
786
+ view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
787
+ view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
788
+ view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
1158
789
  }
1159
-
1160
- // schedule decryption keys
1161
- for (let j = 0; i; j++, i--) {
1162
- const tmp = encKey[j & 3 ? i : i - 4];
1163
- if (i <= 4 || j < 4) {
1164
- decKey[j] = tmp;
1165
- } else {
1166
- decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
1167
- decTable[1][sbox[tmp >> 16 & 255]] ^
1168
- decTable[2][sbox[tmp >> 8 & 255]] ^
1169
- decTable[3][sbox[tmp & 255]];
1170
- }
1171
- }
1172
- }
1173
- // public
1174
- /* Something like this might appear here eventually
1175
- name: "AES",
1176
- blockSize: 4,
1177
- keySizes: [4,6,8],
1178
- */
1179
-
1180
- /**
1181
- * Encrypt an array of 4 big-endian words.
1182
- * @param {Array} data The plaintext.
1183
- * @return {Array} The ciphertext.
1184
- */
1185
- encrypt(data) {
1186
- return this._crypt(data, 0);
1187
- }
1188
-
1189
- /**
1190
- * Decrypt an array of 4 big-endian words.
1191
- * @param {Array} data The ciphertext.
1192
- * @return {Array} The plaintext.
1193
- */
1194
- decrypt(data) {
1195
- return this._crypt(data, 1);
1196
- }
1197
-
1198
- /**
1199
- * Expand the S-box tables.
1200
- *
1201
- * @private
1202
- */
1203
- _precompute() {
1204
- const encTable = this._tables[0];
1205
- const decTable = this._tables[1];
1206
- const sbox = encTable[4];
1207
- const sboxInv = decTable[4];
1208
- const d = [];
1209
- const th = [];
1210
- let xInv, x2, x4, x8;
1211
-
1212
- // Compute double and third tables
1213
- for (let i = 0; i < 256; i++) {
1214
- th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
1215
- }
1216
-
1217
- for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
1218
- // Compute sbox
1219
- let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
1220
- s = s >> 8 ^ s & 255 ^ 99;
1221
- sbox[x] = s;
1222
- sboxInv[s] = x;
1223
-
1224
- // Compute MixColumns
1225
- x8 = d[x4 = d[x2 = d[x]]];
1226
- let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
1227
- let tEnc = d[s] * 0x101 ^ s * 0x1010100;
1228
-
1229
- for (let i = 0; i < 4; i++) {
1230
- encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
1231
- decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
1232
- }
1233
- }
1234
-
1235
- // Compactify. Considerable speedup on Firefox.
1236
- for (let i = 0; i < 5; i++) {
1237
- encTable[i] = encTable[i].slice(0);
1238
- decTable[i] = decTable[i].slice(0);
1239
- }
1240
- }
1241
-
1242
- /**
1243
- * Encryption and decryption core.
1244
- * @param {Array} input Four words to be encrypted or decrypted.
1245
- * @param dir The direction, 0 for encrypt and 1 for decrypt.
1246
- * @return {Array} The four encrypted or decrypted words.
1247
- * @private
1248
- */
1249
- _crypt(input, dir) {
1250
- if (input.length !== 4) {
1251
- throw new Error("invalid aes block size");
1252
- }
1253
-
1254
- const key = this._key[dir];
1255
-
1256
- const nInnerRounds = key.length / 4 - 2;
1257
- const out = [0, 0, 0, 0];
1258
- const table = this._tables[dir];
1259
-
1260
- // load up the tables
1261
- const t0 = table[0];
1262
- const t1 = table[1];
1263
- const t2 = table[2];
1264
- const t3 = table[3];
1265
- const sbox = table[4];
1266
-
1267
- // state variables a,b,c,d are loaded with pre-whitened data
1268
- let a = input[0] ^ key[0];
1269
- let b = input[dir ? 3 : 1] ^ key[1];
1270
- let c = input[2] ^ key[2];
1271
- let d = input[dir ? 1 : 3] ^ key[3];
1272
- let kIndex = 4;
1273
- let a2, b2, c2;
1274
-
1275
- // Inner rounds. Cribbed from OpenSSL.
1276
- for (let i = 0; i < nInnerRounds; i++) {
1277
- a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
1278
- b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
1279
- c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
1280
- d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
1281
- kIndex += 4;
1282
- a = a2; b = b2; c = c2;
1283
- }
1284
-
1285
- // Last round.
1286
- for (let i = 0; i < 4; i++) {
1287
- out[dir ? 3 & -i : i] =
1288
- sbox[a >>> 24] << 24 ^
1289
- sbox[b >> 16 & 255] << 16 ^
1290
- sbox[c >> 8 & 255] << 8 ^
1291
- sbox[d & 255] ^
1292
- key[kIndex++];
1293
- a2 = a; a = b; b = c; c = d; d = a2;
1294
- }
1295
-
1296
- return out;
1297
- }
1298
- };
1299
-
1300
- /** @fileOverview CTR mode implementation.
1301
- *
1302
- * Special thanks to Roy Nicholson for pointing out a bug in our
1303
- * implementation.
1304
- *
1305
- * @author Emily Stark
1306
- * @author Mike Hamburg
1307
- * @author Dan Boneh
1308
- */
1309
-
1310
- /** Brian Gladman's CTR Mode.
1311
- * @constructor
1312
- * @param {Object} _prf The aes instance to generate key.
1313
- * @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
1314
- */
1315
-
1316
- const mode = {};
1317
-
1318
- /**
1319
- * Brian Gladman's CTR Mode.
1320
- * @namespace
1321
- */
1322
- mode.ctrGladman = class {
1323
- constructor(prf, iv) {
1324
- this._prf = prf;
1325
- this._initIv = iv;
1326
- this._iv = iv;
1327
- }
1328
-
1329
- reset() {
1330
- this._iv = this._initIv;
1331
- }
1332
-
1333
- /** Input some data to calculate.
1334
- * @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
1335
- */
1336
- update(data) {
1337
- return this.calculate(this._prf, data, this._iv);
1338
- }
1339
-
1340
- incWord(word) {
1341
- if (((word >> 24) & 0xff) === 0xff) { //overflow
1342
- let b1 = (word >> 16) & 0xff;
1343
- let b2 = (word >> 8) & 0xff;
1344
- let b3 = word & 0xff;
1345
-
1346
- if (b1 === 0xff) { // overflow b1
1347
- b1 = 0;
1348
- if (b2 === 0xff) {
1349
- b2 = 0;
1350
- if (b3 === 0xff) {
1351
- b3 = 0;
1352
- } else {
1353
- ++b3;
1354
- }
1355
- } else {
1356
- ++b2;
1357
- }
1358
- } else {
1359
- ++b1;
790
+ if (offset < length) {
791
+ nextKeystream();
792
+ for (let indexByte = 0; offset < length; offset++, indexByte++) {
793
+ data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
1360
794
  }
1361
-
1362
- word = 0;
1363
- word += (b1 << 16);
1364
- word += (b2 << 8);
1365
- word += b3;
1366
- } else {
1367
- word += (0x01 << 24);
1368
795
  }
1369
- return word;
1370
796
  }
1371
797
 
1372
- incCounter(counter) {
1373
- if ((counter[0] = this.incWord(counter[0])) === 0) {
1374
- // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
1375
- counter[1] = this.incWord(counter[1]);
1376
- }
1377
- }
1378
-
1379
- calculate(prf, data, iv) {
1380
- let l;
1381
- if (!(l = data.length)) {
1382
- return [];
1383
- }
1384
- const bl = bitArray.bitLength(data);
1385
- for (let i = 0; i < l; i += 4) {
1386
- this.incCounter(iv);
1387
- const e = prf.encrypt(iv);
1388
- data[i] ^= e[0];
1389
- data[i + 1] ^= e[1];
1390
- data[i + 2] ^= e[2];
1391
- data[i + 3] ^= e[3];
1392
- }
1393
- return bitArray.clamp(data, bl);
1394
- }
1395
- };
1396
-
1397
- const misc = {
1398
- importKey(password) {
1399
- return new misc.hmacSha1(codec.bytes.toBits(password));
1400
- },
1401
- pbkdf2(prf, salt, count, length) {
1402
- count = count || 10000;
1403
- if (length < 0 || count < 0) {
1404
- throw new Error("invalid params to pbkdf2");
1405
- }
1406
- const byteLength = ((length >> 5) + 1) << 2;
1407
- let u, ui, i, j, k;
1408
- const arrayBuffer = new ArrayBuffer(byteLength);
1409
- const out = new DataView(arrayBuffer);
1410
- let outLength = 0;
1411
- const b = bitArray;
1412
- salt = codec.bytes.toBits(salt);
1413
- for (k = 1; outLength < (byteLength || 1); k++) {
1414
- u = ui = prf.encrypt(b.concat(salt, [k]));
1415
- for (i = 1; i < count; i++) {
1416
- ui = prf.encrypt(ui);
1417
- for (j = 0; j < ui.length; j++) {
1418
- u[j] ^= ui[j];
798
+ function nextKeystream() {
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;
1419
806
  }
1420
807
  }
1421
- for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
1422
- out.setInt32(outLength, u[i]);
1423
- outLength += 4;
1424
- }
1425
808
  }
1426
- return arrayBuffer.slice(0, length / 8);
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];
876
+ }
877
+ }
878
+
879
+ function pbkdf2(password, salt, iterations, length) {
880
+ const hmac = createHmac(password);
881
+ const result = new Uint8Array(length);
882
+ const block = new Uint8Array(salt.length + 4);
883
+ const blockView = new DataView(block.buffer);
884
+ block.set(salt);
885
+ for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
886
+ blockView.setUint32(salt.length, indexBlock);
887
+ hmac.update(block, 0, block.length);
888
+ let previous = hmac.digest();
889
+ const output = previous.slice();
890
+ for (let iteration = 1; iteration < iterations; iteration++) {
891
+ hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
892
+ previous = hmac.digest();
893
+ for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
894
+ output[indexByte] ^= previous[indexByte];
895
+ }
896
+ }
897
+ result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
1427
898
  }
1428
- };
1429
-
1430
- /** @fileOverview HMAC implementation.
1431
- *
1432
- * @author Emily Stark
1433
- * @author Mike Hamburg
1434
- * @author Dan Boneh
1435
- */
1436
-
1437
- /** HMAC with the specified hash function.
1438
- * @constructor
1439
- * @param {bitArray} key the key for HMAC.
1440
- * @param {Object} [Hash=hash.sha1] The hash function to use.
1441
- */
1442
- misc.hmacSha1 = class {
1443
-
1444
- constructor(key) {
1445
- const hmac = this;
1446
- const Hash = hmac._hash = hash.sha1;
1447
- const exKey = [[], []];
1448
- hmac._baseHash = [new Hash(), new Hash()];
1449
- const bs = hmac._baseHash[0].blockSize / 32;
1450
-
1451
- if (key.length > bs) {
1452
- key = new Hash().update(key).finalize();
1453
- }
1454
-
1455
- for (let i = 0; i < bs; i++) {
1456
- exKey[0][i] = key[i] ^ 0x36363636;
1457
- exKey[1][i] = key[i] ^ 0x5C5C5C5C;
1458
- }
899
+ return result;
900
+ }
1459
901
 
1460
- hmac._baseHash[0].update(exKey[0]);
1461
- hmac._baseHash[1].update(exKey[1]);
1462
- hmac._resultHash = new Hash(hmac._baseHash[0]);
902
+ function createHmac(key) {
903
+ const sha1 = createSha1();
904
+ const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
905
+ const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
906
+ if (key.length > SHA1_BLOCK_LENGTH) {
907
+ sha1.update(key, 0, key.length);
908
+ key = sha1.digest();
1463
909
  }
1464
- reset() {
1465
- const hmac = this;
1466
- hmac._resultHash = new hmac._hash(hmac._baseHash[0]);
1467
- hmac._updated = false;
910
+ for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
911
+ const keyByte = indexByte < key.length ? key[indexByte] : 0;
912
+ innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
913
+ outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
1468
914
  }
915
+ sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
916
+ return {
917
+ update(data, offset, length) {
918
+ sha1.update(data, offset, length);
919
+ },
920
+ digest() {
921
+ const innerDigest = sha1.digest();
922
+ sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
923
+ sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
924
+ const result = sha1.digest();
925
+ sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
926
+ return result;
927
+ }
928
+ };
929
+ }
1469
930
 
1470
- update(data) {
1471
- const hmac = this;
1472
- hmac._updated = true;
1473
- hmac._resultHash.update(data);
1474
- }
1475
-
1476
- digest() {
1477
- const hmac = this;
1478
- const w = hmac._resultHash.finalize();
1479
- const result = new (hmac._hash)(hmac._baseHash[1]).update(w).finalize();
1480
-
1481
- hmac.reset();
931
+ function createSha1() {
932
+ const state = new Int32Array(SHA1_INITIAL_STATE);
933
+ const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
934
+ const block = new Uint8Array(SHA1_BLOCK_LENGTH);
935
+ const blockView = new DataView(block.buffer);
936
+ const lengthBytes = new Uint8Array(8);
937
+ let blockLength = 0;
938
+ let totalLength = 0;
939
+ return {
940
+ update,
941
+ digest
942
+ };
1482
943
 
944
+ function update(data, offset, length) {
945
+ const end = offset + length;
946
+ totalLength += length;
947
+ if (blockLength) {
948
+ while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
949
+ block[blockLength++] = data[offset++];
950
+ }
951
+ if (blockLength == SHA1_BLOCK_LENGTH) {
952
+ compress(blockView, 0);
953
+ blockLength = 0;
954
+ }
955
+ }
956
+ if (offset + SHA1_BLOCK_LENGTH <= end) {
957
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
958
+ for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
959
+ compress(view, offset);
960
+ }
961
+ }
962
+ while (offset < end) {
963
+ block[blockLength++] = data[offset++];
964
+ }
965
+ }
966
+
967
+ function digest() {
968
+ const bits = totalLength * 8;
969
+ const high = Math.floor(bits / 0x100000000);
970
+ const low = bits >>> 0;
971
+ update(SHA1_PADDING, 0, 1);
972
+ while (blockLength != SHA1_LENGTH_OFFSET) {
973
+ update(SHA1_ZERO, 0, 1);
974
+ }
975
+ lengthBytes[0] = high >>> 24;
976
+ lengthBytes[1] = high >>> 16;
977
+ lengthBytes[2] = high >>> 8;
978
+ lengthBytes[3] = high;
979
+ lengthBytes[4] = low >>> 24;
980
+ lengthBytes[5] = low >>> 16;
981
+ lengthBytes[6] = low >>> 8;
982
+ lengthBytes[7] = low;
983
+ update(lengthBytes, 0, 8);
984
+ const result = new Uint8Array(SHA1_DIGEST_LENGTH);
985
+ const resultView = new DataView(result.buffer);
986
+ for (let indexWord = 0; indexWord < state.length; indexWord++) {
987
+ resultView.setInt32(4 * indexWord, state[indexWord]);
988
+ }
989
+ state.set(SHA1_INITIAL_STATE);
990
+ blockLength = 0;
991
+ totalLength = 0;
1483
992
  return result;
1484
993
  }
1485
994
 
1486
- encrypt(data) {
1487
- if (!this._updated) {
1488
- this.update(data);
1489
- return this.digest(data);
1490
- } else {
1491
- throw new Error("encrypt on already updated hmac called!");
1492
- }
1493
- }
1494
- };
995
+ function compress(view, offset) {
996
+ for (let index = 0; index < 16; index++) {
997
+ schedule[index] = view.getInt32(offset + 4 * index);
998
+ }
999
+ let a = state[0];
1000
+ let b = state[1];
1001
+ let c = state[2];
1002
+ let d = state[3];
1003
+ let e = state[4];
1004
+ let 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);
1119
+ }
1120
+ state[0] = (state[0] + a) | 0;
1121
+ state[1] = (state[1] + b) | 0;
1122
+ state[2] = (state[2] + c) | 0;
1123
+ state[3] = (state[3] + d) | 0;
1124
+ state[4] = (state[4] + e) | 0;
1125
+ }
1126
+ }
1127
+
1128
+ function initTables() {
1129
+ if (!tablesInitialized) {
1130
+ let p = 1;
1131
+ let q = 1;
1132
+ do {
1133
+ p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
1134
+ q = (q ^ (q << 1)) & 255;
1135
+ q = (q ^ (q << 2)) & 255;
1136
+ q = (q ^ (q << 4)) & 255;
1137
+ if (q & 0x80) {
1138
+ q ^= 0x09;
1139
+ }
1140
+ S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
1141
+ } while (p != 1);
1142
+ S_BOX[0] = 0x63;
1143
+ for (let index = 0; index < 256; index++) {
1144
+ const s = S_BOX[index];
1145
+ const s2 = multiplyByTwo(s);
1146
+ const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
1147
+ T0[index] = t;
1148
+ T1[index] = (t >>> 8) | (t << 24);
1149
+ T2[index] = (t >>> 16) | (t << 16);
1150
+ T3[index] = (t >>> 24) | (t << 8);
1151
+ }
1152
+ tablesInitialized = true;
1153
+ }
1154
+ }
1155
+
1156
+ function expandKey(key, roundKeys) {
1157
+ const keyWords = key.length >> 2;
1158
+ const rounds = keyWords + 6;
1159
+ const total = 4 * (rounds + 1);
1160
+ let roundConstant = 1;
1161
+ for (let index = 0; index < keyWords; index++) {
1162
+ roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
1163
+ }
1164
+ for (let index = keyWords; index < total; index++) {
1165
+ let word = roundKeys[index - 1];
1166
+ if (index % keyWords == 0) {
1167
+ word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
1168
+ roundConstant = multiplyByTwo(roundConstant);
1169
+ } else if (keyWords > 6 && index % keyWords == 4) {
1170
+ word = substituteWord(word);
1171
+ }
1172
+ roundKeys[index] = roundKeys[index - keyWords] ^ word;
1173
+ }
1174
+ return rounds;
1175
+ }
1176
+
1177
+ function substituteWord(word) {
1178
+ return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
1179
+ }
1180
+
1181
+ function swapBytes(value) {
1182
+ return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
1183
+ }
1184
+
1185
+ function multiplyByTwo(value) {
1186
+ return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
1187
+ }
1495
1188
 
1496
1189
  /*
1497
1190
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
@@ -1546,8 +1239,8 @@
1546
1239
  1. Redistributions of source code must retain the above copyright notice,
1547
1240
  this list of conditions and the following disclaimer.
1548
1241
 
1549
- 2. Redistributions in binary form must reproduce the above copyright
1550
- notice, this list of conditions and the following disclaimer in
1242
+ 2. Redistributions in binary form must reproduce the above copyright
1243
+ notice, this list of conditions and the following disclaimer in
1551
1244
  the documentation and/or other materials provided with the distribution.
1552
1245
 
1553
1246
  3. The names of the authors may not be used to endorse or promote products
@@ -1571,24 +1264,21 @@
1571
1264
  const PBKDF2_ALGORITHM = { name: "PBKDF2" };
1572
1265
  const HASH_ALGORITHM = { name: "HMAC" };
1573
1266
  const HASH_FUNCTION = "SHA-1";
1267
+ const PBKDF2_ITERATIONS = 1000;
1574
1268
  const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
1575
- const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: 1000, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
1269
+ const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: PBKDF2_ITERATIONS, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
1576
1270
  const DERIVED_BITS_USAGE = ["deriveBits"];
1577
1271
  const SALT_LENGTH = [8, 12, 16];
1578
1272
  const KEY_LENGTH = [16, 24, 32];
1579
1273
  const AUTHENTICATION_CODE_LENGTH = 10;
1580
- const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
1274
+ const PASSWORD_VERIFICATION_LENGTH = 2;
1581
1275
  // deno-lint-ignore valid-typeof
1582
1276
  const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
1583
1277
  const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
1584
1278
  const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
1585
- const codecBytes = codec.bytes;
1586
- const Aes = cipher.aes;
1587
- const CtrGladman = mode.ctrGladman;
1588
- const HmacSha1 = misc.hmacSha1;
1589
1279
 
1590
- let IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE;
1591
- let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof subtle.deriveBits == FUNCTION_TYPE;
1280
+ let DERIVE_BITS_SUPPORTED = SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE && typeof subtle.deriveBits == FUNCTION_TYPE;
1281
+ let createEngine = createEngine$1;
1592
1282
 
1593
1283
  class AESDecryptionStream extends TransformStream {
1594
1284
 
@@ -1606,9 +1296,10 @@
1606
1296
  ready
1607
1297
  } = aesCrypto;
1608
1298
  if (password) {
1609
- await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + 2));
1610
- chunk = subarray(chunk, SALT_LENGTH[strength] + 2);
1299
+ await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH));
1300
+ chunk = subarray(chunk, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH);
1611
1301
  if (checkPasswordOnly) {
1302
+ disposeEngine(aesCrypto);
1612
1303
  controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
1613
1304
  } else {
1614
1305
  resolveReady();
@@ -1621,23 +1312,16 @@
1621
1312
  },
1622
1313
  async flush(controller) {
1623
1314
  const {
1624
- ctr,
1625
- hmac,
1315
+ engine,
1626
1316
  pendingInput,
1627
1317
  ready
1628
1318
  } = this;
1629
- if (hmac && ctr) {
1319
+ if (engine) {
1630
1320
  await ready;
1631
- const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1632
1321
  const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1633
- let decryptedChunkArray = EMPTY_UINT8_ARRAY;
1634
- if (chunkToDecrypt.length) {
1635
- const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
1636
- hmac.update(encryptedChunk);
1637
- const decryptedChunk = ctr.update(encryptedChunk);
1638
- decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
1639
- }
1640
- const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
1322
+ const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
1323
+ engine.process(decryptedChunkArray, true);
1324
+ const authenticationCode = engine.digest();
1641
1325
  let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
1642
1326
  for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
1643
1327
  invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
@@ -1647,6 +1331,9 @@
1647
1331
  }
1648
1332
  controller.enqueue(decryptedChunkArray);
1649
1333
  }
1334
+ },
1335
+ cancel() {
1336
+ disposeEngine(this);
1650
1337
  }
1651
1338
  });
1652
1339
  }
@@ -1676,26 +1363,24 @@
1676
1363
  }
1677
1364
  const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
1678
1365
  output.set(preamble, 0);
1679
- controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
1366
+ controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
1680
1367
  },
1681
1368
  async flush(controller) {
1682
1369
  const {
1683
- ctr,
1684
- hmac,
1370
+ engine,
1685
1371
  pendingInput,
1686
1372
  ready
1687
1373
  } = this;
1688
- if (hmac && ctr) {
1374
+ if (engine) {
1689
1375
  await ready;
1690
- let encryptedChunkArray = EMPTY_UINT8_ARRAY;
1691
- if (pendingInput.length) {
1692
- const encryptedChunk = ctr.update(toBits(codecBytes, pendingInput));
1693
- hmac.update(encryptedChunk);
1694
- encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
1695
- }
1696
- const authenticationCode = fromBits(codecBytes, hmac.digest()).slice(0, AUTHENTICATION_CODE_LENGTH);
1376
+ const encryptedChunkArray = new Uint8Array(pendingInput);
1377
+ engine.process(encryptedChunkArray, false);
1378
+ const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
1697
1379
  controller.enqueue(concat(encryptedChunkArray, authenticationCode));
1698
1380
  }
1381
+ },
1382
+ cancel() {
1383
+ disposeEngine(this);
1699
1384
  }
1700
1385
  });
1701
1386
  }
@@ -1710,30 +1395,23 @@
1710
1395
  });
1711
1396
  }
1712
1397
 
1713
- function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthenticationCode) {
1398
+ function append(aesCrypto, input, output, paddingStart, paddingEnd, decrypt) {
1714
1399
  const {
1715
- ctr,
1716
- hmac,
1400
+ engine,
1717
1401
  pendingInput
1718
1402
  } = aesCrypto;
1719
1403
  if (pendingInput.length) {
1720
1404
  input = concat(pendingInput, input);
1721
1405
  }
1722
1406
  const inputLength = input.length - paddingEnd;
1723
- output = expand(output, paddingStart + (inputLength - (inputLength % BLOCK_LENGTH)));
1724
- let offset;
1725
- for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
1726
- const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
1727
- if (verifyAuthenticationCode) {
1728
- hmac.update(inputChunk);
1729
- }
1730
- const outputChunk = ctr.update(inputChunk);
1731
- if (!verifyAuthenticationCode) {
1732
- hmac.update(outputChunk);
1733
- }
1734
- output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
1735
- }
1736
- aesCrypto.pendingInput = subarray(input, offset);
1407
+ const alignedLength = inputLength - (inputLength % BLOCK_LENGTH);
1408
+ output = expand(output, paddingStart + alignedLength);
1409
+ if (alignedLength) {
1410
+ const chunk = subarray(output, paddingStart, paddingStart + alignedLength);
1411
+ chunk.set(subarray(input, 0, alignedLength));
1412
+ engine.process(chunk, decrypt);
1413
+ }
1414
+ aesCrypto.pendingInput = subarray(input, alignedLength);
1737
1415
  return output;
1738
1416
  }
1739
1417
 
@@ -1741,10 +1419,17 @@
1741
1419
  const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
1742
1420
  const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
1743
1421
  if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
1422
+ disposeEngine(decrypt);
1744
1423
  throw new Error(ERR_INVALID_PASSWORD);
1745
1424
  }
1746
1425
  }
1747
1426
 
1427
+ function disposeEngine({ engine }) {
1428
+ if (engine && engine.dispose) {
1429
+ engine.dispose();
1430
+ }
1431
+ }
1432
+
1748
1433
  async function createEncryptionKeys(encrypt, strength, password) {
1749
1434
  const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
1750
1435
  const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
@@ -1753,48 +1438,22 @@
1753
1438
 
1754
1439
  async function createKeys$1(aesCrypto, strength, password, salt) {
1755
1440
  aesCrypto.password = null;
1756
- const baseKey = await importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
1757
- const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2));
1758
- const compositeKey = new Uint8Array(derivedBits);
1759
- const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength]));
1760
- const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
1761
- const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
1762
- Object.assign(aesCrypto, {
1763
- keys: {
1764
- key,
1765
- authentication,
1766
- passwordVerification
1767
- },
1768
- ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)),
1769
- hmac: new HmacSha1(authentication)
1770
- });
1771
- return passwordVerification;
1441
+ const keyLength = KEY_LENGTH[strength];
1442
+ const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
1443
+ aesCrypto.engine = createEngine(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
1444
+ return subarray(compositeKey, keyLength * 2);
1772
1445
  }
1773
1446
 
1774
- async function importKey(format, password, algorithm, extractable, keyUsages) {
1775
- if (IMPORT_KEY_SUPPORTED) {
1776
- try {
1777
- return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
1778
- } catch {
1779
- IMPORT_KEY_SUPPORTED = false;
1780
- return misc.importKey(password);
1781
- }
1782
- } else {
1783
- return misc.importKey(password);
1784
- }
1785
- }
1786
-
1787
- async function deriveBits(algorithm, baseKey, length) {
1447
+ async function deriveKey(password, salt, length) {
1788
1448
  if (DERIVE_BITS_SUPPORTED) {
1789
1449
  try {
1790
- return await subtle.deriveBits(algorithm, baseKey, length);
1450
+ const baseKey = await subtle.importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
1451
+ return new Uint8Array(await subtle.deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, length * 8));
1791
1452
  } catch {
1792
1453
  DERIVE_BITS_SUPPORTED = false;
1793
- return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
1794
1454
  }
1795
- } else {
1796
- return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
1797
1455
  }
1456
+ return pbkdf2(password, salt, PBKDF2_ITERATIONS, length);
1798
1457
  }
1799
1458
 
1800
1459
  function encodePassword(password, rawPassword) {
@@ -1818,13 +1477,6 @@
1818
1477
  return array.subarray(begin, end);
1819
1478
  }
1820
1479
 
1821
- function fromBits(codecBytes, chunk) {
1822
- return codecBytes.fromBits(chunk);
1823
- }
1824
- function toBits(codecBytes, chunk) {
1825
- return codecBytes.toBits(chunk);
1826
- }
1827
-
1828
1480
  /*
1829
1481
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
1830
1482
 
@@ -2764,11 +2416,18 @@
2764
2416
  return true;
2765
2417
  }
2766
2418
  if (FallbackStream) {
2419
+ return await loadModule(config);
2420
+ }
2421
+ return false;
2422
+ }
2423
+
2424
+ async function loadModule(config) {
2425
+ if (initModule) {
2767
2426
  try {
2768
2427
  await initModule(config);
2769
2428
  return true;
2770
2429
  } catch {
2771
- return false;
2430
+ // ignored
2772
2431
  }
2773
2432
  }
2774
2433
  return false;
@@ -2811,27 +2470,29 @@
2811
2470
  terminate() {
2812
2471
  return new Promise(resolve => {
2813
2472
  const { worker, busy } = workerData;
2814
- if (worker) {
2815
- if (busy) {
2816
- workerData.resolveTerminated = resolve;
2817
- } else {
2473
+ if (busy) {
2474
+ workerData.terminateResolvers = workerData.terminateResolvers || [];
2475
+ workerData.terminateResolvers.push(resolve);
2476
+ } else {
2477
+ if (worker) {
2818
2478
  worker.terminate();
2819
- resolve();
2479
+ workerData.worker = null;
2820
2480
  }
2821
- workerData.interface = null;
2822
- } else {
2823
2481
  resolve();
2824
2482
  }
2483
+ workerData.interface = null;
2825
2484
  });
2826
2485
  },
2827
2486
  onTaskFinished() {
2828
2487
  if (workerData.busy) {
2829
- const { resolveTerminated } = workerData;
2830
- if (resolveTerminated) {
2831
- workerData.resolveTerminated = null;
2832
- workerData.terminated = true;
2833
- workerData.worker.terminate();
2834
- resolveTerminated();
2488
+ const { terminateResolvers, worker } = workerData;
2489
+ if (terminateResolvers) {
2490
+ workerData.terminateResolvers = null;
2491
+ if (worker) {
2492
+ workerData.terminated = true;
2493
+ worker.terminate();
2494
+ }
2495
+ terminateResolvers.forEach(resolve => resolve());
2835
2496
  }
2836
2497
  workerData.busy = false;
2837
2498
  onTaskFinished(workerData);
@@ -2887,28 +2548,23 @@
2887
2548
  }
2888
2549
 
2889
2550
  async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
2890
- let codecStream, chunkStream;
2551
+ let codecStream, chunkStream, modulePromise;
2891
2552
  try {
2892
2553
  if (options.compressed && !options.format) {
2893
2554
  const deflate = options.codecType.startsWith(CODEC_DEFLATE);
2894
2555
  const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
2895
2556
  const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
2896
2557
  if (!options.useCompressionStream) {
2897
- try {
2898
- await initModule(config);
2899
- } catch {
2900
- if (!FallbackStream || FallbackStream.requiresModule) {
2901
- options.useCompressionStream = true;
2902
- }
2558
+ if (!await moduleLoaded() && (!FallbackStream || FallbackStream.requiresModule)) {
2559
+ options.useCompressionStream = true;
2903
2560
  }
2904
2561
  } else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
2905
- try {
2906
- await initModule(config);
2907
- } catch {
2908
- // ignored
2909
- }
2562
+ await moduleLoaded();
2910
2563
  }
2911
2564
  }
2565
+ if (options.encrypted && !options.zipCrypto) {
2566
+ await moduleLoaded();
2567
+ }
2912
2568
  codecStream = new CodecStream(options, config);
2913
2569
  chunkStream = new ChunkStream(getChunkSize(config));
2914
2570
  await readable
@@ -2941,6 +2597,13 @@
2941
2597
  } finally {
2942
2598
  onTaskFinished();
2943
2599
  }
2600
+
2601
+ function moduleLoaded() {
2602
+ if (!modulePromise) {
2603
+ modulePromise = loadModule(config);
2604
+ }
2605
+ return modulePromise;
2606
+ }
2944
2607
  }
2945
2608
 
2946
2609
  /*
@@ -4077,16 +3740,14 @@
4077
3740
  combineSizeEocd
4078
3741
  } = httpReader;
4079
3742
  if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
4080
- const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
3743
+ const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
4081
3744
  const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
4082
3745
  if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
4083
3746
  throw new Error(ERR_HTTP_RANGE);
4084
3747
  } else {
4085
- if (combineSizeEocd) {
4086
- const eocdCache = new Uint8Array(await response.arrayBuffer());
4087
- if (response.status == 206 && eocdCache.length == END_OF_CENTRAL_DIR_LENGTH) {
4088
- httpReader.eocdCache = eocdCache;
4089
- }
3748
+ let eocdCache;
3749
+ if (combineSizeEocd && response.status == 206) {
3750
+ eocdCache = new Uint8Array(await response.arrayBuffer());
4090
3751
  }
4091
3752
  setResourceValidators(httpReader, response);
4092
3753
  const contentSize = getContentRangeSize(response);
@@ -4095,6 +3756,9 @@
4095
3756
  } else {
4096
3757
  httpReader.size = contentSize;
4097
3758
  }
3759
+ if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
3760
+ httpReader.eocdCache = eocdCache;
3761
+ }
4098
3762
  }
4099
3763
  } else {
4100
3764
  await getContentLength(httpReader, sendRequest, getRequestData);
@@ -4110,25 +3774,23 @@
4110
3774
  options
4111
3775
  } = httpReader;
4112
3776
  if (useRangeHeader || forceRangeRequests) {
4113
- if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
4114
- return eocdCache;
4115
- }
4116
3777
  if (index >= size || length === 0) {
4117
3778
  return EMPTY_UINT8_ARRAY;
4118
3779
  } else {
4119
3780
  if (index + length > size) {
4120
3781
  length = size - index;
4121
3782
  }
3783
+ if (eocdCache && index >= size - eocdCache.length) {
3784
+ const cacheIndex = index - (size - eocdCache.length);
3785
+ return eocdCache.slice(cacheIndex, cacheIndex + length);
3786
+ }
4122
3787
  const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
4123
3788
  if (response.status != 206) {
4124
3789
  throw new Error(ERR_HTTP_RANGE);
4125
3790
  }
4126
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4127
- if (contentRangeHeader) {
4128
- const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
4129
- if (!Number.isNaN(rangeStart) && rangeStart != index) {
4130
- throw new Error(ERR_HTTP_RANGE);
4131
- }
3791
+ const rangeStart = getContentRangeOffset(response);
3792
+ if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
3793
+ throw new Error(ERR_HTTP_RANGE);
4132
3794
  }
4133
3795
  checkResourceValidators(httpReader, response);
4134
3796
  setResourceValidators(httpReader, response);
@@ -4188,12 +3850,9 @@
4188
3850
  if (response.status != 206) {
4189
3851
  throw new Error(ERR_HTTP_RANGE);
4190
3852
  }
4191
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4192
- if (contentRangeHeader) {
4193
- const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
4194
- if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
4195
- throw new Error(ERR_HTTP_RANGE);
4196
- }
3853
+ const rangeStart = getContentRangeOffset(response);
3854
+ if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
3855
+ throw new Error(ERR_HTTP_RANGE);
4197
3856
  }
4198
3857
  checkResourceValidators(httpReader, response);
4199
3858
  setResourceValidators(httpReader, response);
@@ -4209,6 +3868,16 @@
4209
3868
  }
4210
3869
  }
4211
3870
 
3871
+ function getContentRangeOffset(response) {
3872
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
3873
+ if (contentRangeHeader) {
3874
+ const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
3875
+ if (!Number.isNaN(rangeStart)) {
3876
+ return rangeStart;
3877
+ }
3878
+ }
3879
+ }
3880
+
4212
3881
  function getContentRangeSize(response) {
4213
3882
  const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4214
3883
  if (contentRangeHeader) {
@@ -4989,7 +4658,7 @@
4989
4658
  Object.assign(this, {
4990
4659
  reader: new GenericReader(reader),
4991
4660
  options,
4992
- readRanges: new Map()
4661
+ readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
4993
4662
  });
4994
4663
  }
4995
4664
 
@@ -5634,7 +5303,6 @@
5634
5303
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5635
5304
  }
5636
5305
  const size = compressedSize;
5637
- const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5638
5306
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5639
5307
  throwIfAborted(signal);
5640
5308
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -5708,6 +5376,7 @@
5708
5376
  writer = new GenericWriter(writer);
5709
5377
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5710
5378
  ({ writable } = writer);
5379
+ const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5711
5380
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5712
5381
  if (writtenSize != outputSize) {
5713
5382
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
@@ -6143,14 +5812,61 @@
6143
5812
  end: dataOffset + compressedSize + dataDescriptorLength,
6144
5813
  fileEntry
6145
5814
  };
6146
- for (const [otherIndex, otherRange] of readRanges) {
6147
- if (otherIndex != index && range.start < otherRange.end && otherRange.start < range.end) {
5815
+ const { indexes, sortedRanges, pendingRanges } = readRanges;
5816
+ if (!indexes.has(index)) {
5817
+ const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
5818
+ if (overlappingRange) {
6148
5819
  const error = new Error(ERR_OVERLAPPING_ENTRY);
6149
- error.overlappingEntry = otherRange.fileEntry;
5820
+ error.overlappingEntry = overlappingRange.fileEntry;
6150
5821
  throw error;
6151
5822
  }
5823
+ indexes.add(index);
5824
+ pendingRanges.push(range);
5825
+ if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
5826
+ pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
5827
+ readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
5828
+ pendingRanges.length = 0;
5829
+ }
5830
+ }
5831
+ }
5832
+
5833
+ function findOverlappingRange(sortedRanges, range) {
5834
+ let low = 0;
5835
+ let high = sortedRanges.length;
5836
+ while (low < high) {
5837
+ const middle = (low + high) >>> 1;
5838
+ if (sortedRanges[middle].start < range.start) {
5839
+ low = middle + 1;
5840
+ } else {
5841
+ high = middle;
5842
+ }
5843
+ }
5844
+ const previousRange = sortedRanges[low - 1];
5845
+ const nextRange = sortedRanges[low];
5846
+ if (previousRange && rangesOverlap(range, previousRange)) {
5847
+ return previousRange;
5848
+ }
5849
+ if (nextRange && rangesOverlap(range, nextRange)) {
5850
+ return nextRange;
5851
+ }
5852
+ }
5853
+
5854
+ function rangesOverlap(range, otherRange) {
5855
+ return range.start < otherRange.end && otherRange.start < range.end;
5856
+ }
5857
+
5858
+ function mergeRanges(sortedRanges, pendingRanges) {
5859
+ const mergedRanges = [];
5860
+ let indexSorted = 0;
5861
+ let indexPending = 0;
5862
+ while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
5863
+ if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
5864
+ mergedRanges.push(sortedRanges[indexSorted++]);
5865
+ } else {
5866
+ mergedRanges.push(pendingRanges[indexPending++]);
5867
+ }
6152
5868
  }
6153
- readRanges.set(index, range);
5869
+ return mergedRanges;
6154
5870
  }
6155
5871
 
6156
5872
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
@@ -6728,7 +6444,6 @@
6728
6444
  rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6729
6445
  rawExtraField,
6730
6446
  rawCentralExtraField: EMPTY_UINT8_ARRAY,
6731
- extendedTimestamp: false,
6732
6447
  headerArray,
6733
6448
  headerView
6734
6449
  });
@@ -7472,7 +7187,7 @@
7472
7187
  }
7473
7188
  }
7474
7189
  const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7475
- if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7190
+ if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7476
7191
  dataDescriptor = false;
7477
7192
  }
7478
7193
  const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
@@ -8984,7 +8699,7 @@
8984
8699
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8985
8700
  */
8986
8701
 
8987
- const VERSION = "2.13.1";
8702
+ const VERSION = "2.14.1";
8988
8703
 
8989
8704
  /*
8990
8705
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.