@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
@@ -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
- }
1369
- return word;
1370
- }
1371
-
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
795
  }
1377
796
  }
1378
797
 
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
  /*
@@ -4097,16 +3760,14 @@
4097
3760
  combineSizeEocd
4098
3761
  } = httpReader;
4099
3762
  if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
4100
- const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -END_OF_CENTRAL_DIR_LENGTH : undefined));
3763
+ const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
4101
3764
  const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
4102
3765
  if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
4103
3766
  throw new Error(ERR_HTTP_RANGE);
4104
3767
  } else {
4105
- if (combineSizeEocd) {
4106
- const eocdCache = new Uint8Array(await response.arrayBuffer());
4107
- if (response.status == 206 && eocdCache.length == END_OF_CENTRAL_DIR_LENGTH) {
4108
- httpReader.eocdCache = eocdCache;
4109
- }
3768
+ let eocdCache;
3769
+ if (combineSizeEocd && response.status == 206) {
3770
+ eocdCache = new Uint8Array(await response.arrayBuffer());
4110
3771
  }
4111
3772
  setResourceValidators(httpReader, response);
4112
3773
  const contentSize = getContentRangeSize(response);
@@ -4115,6 +3776,9 @@
4115
3776
  } else {
4116
3777
  httpReader.size = contentSize;
4117
3778
  }
3779
+ if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
3780
+ httpReader.eocdCache = eocdCache;
3781
+ }
4118
3782
  }
4119
3783
  } else {
4120
3784
  await getContentLength(httpReader, sendRequest, getRequestData);
@@ -4130,25 +3794,23 @@
4130
3794
  options
4131
3795
  } = httpReader;
4132
3796
  if (useRangeHeader || forceRangeRequests) {
4133
- if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
4134
- return eocdCache;
4135
- }
4136
3797
  if (index >= size || length === 0) {
4137
3798
  return EMPTY_UINT8_ARRAY;
4138
3799
  } else {
4139
3800
  if (index + length > size) {
4140
3801
  length = size - index;
4141
3802
  }
3803
+ if (eocdCache && index >= size - eocdCache.length) {
3804
+ const cacheIndex = index - (size - eocdCache.length);
3805
+ return eocdCache.slice(cacheIndex, cacheIndex + length);
3806
+ }
4142
3807
  const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
4143
3808
  if (response.status != 206) {
4144
3809
  throw new Error(ERR_HTTP_RANGE);
4145
3810
  }
4146
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4147
- if (contentRangeHeader) {
4148
- const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
4149
- if (!Number.isNaN(rangeStart) && rangeStart != index) {
4150
- throw new Error(ERR_HTTP_RANGE);
4151
- }
3811
+ const rangeStart = getContentRangeOffset(response);
3812
+ if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
3813
+ throw new Error(ERR_HTTP_RANGE);
4152
3814
  }
4153
3815
  checkResourceValidators(httpReader, response);
4154
3816
  setResourceValidators(httpReader, response);
@@ -4208,12 +3870,9 @@
4208
3870
  if (response.status != 206) {
4209
3871
  throw new Error(ERR_HTTP_RANGE);
4210
3872
  }
4211
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4212
- if (contentRangeHeader) {
4213
- const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
4214
- if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
4215
- throw new Error(ERR_HTTP_RANGE);
4216
- }
3873
+ const rangeStart = getContentRangeOffset(response);
3874
+ if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
3875
+ throw new Error(ERR_HTTP_RANGE);
4217
3876
  }
4218
3877
  checkResourceValidators(httpReader, response);
4219
3878
  setResourceValidators(httpReader, response);
@@ -4229,6 +3888,16 @@
4229
3888
  }
4230
3889
  }
4231
3890
 
3891
+ function getContentRangeOffset(response) {
3892
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
3893
+ if (contentRangeHeader) {
3894
+ const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
3895
+ if (!Number.isNaN(rangeStart)) {
3896
+ return rangeStart;
3897
+ }
3898
+ }
3899
+ }
3900
+
4232
3901
  function getContentRangeSize(response) {
4233
3902
  const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
4234
3903
  if (contentRangeHeader) {
@@ -5009,7 +4678,7 @@
5009
4678
  Object.assign(this, {
5010
4679
  reader: new GenericReader(reader),
5011
4680
  options,
5012
- readRanges: new Map()
4681
+ readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
5013
4682
  });
5014
4683
  }
5015
4684
 
@@ -5654,7 +5323,6 @@
5654
5323
  throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
5655
5324
  }
5656
5325
  const size = compressedSize;
5657
- const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5658
5326
  const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
5659
5327
  throwIfAborted(signal);
5660
5328
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -5728,6 +5396,7 @@
5728
5396
  writer = new GenericWriter(writer);
5729
5397
  await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
5730
5398
  ({ writable } = writer);
5399
+ const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5731
5400
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5732
5401
  if (writtenSize != outputSize) {
5733
5402
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
@@ -6163,14 +5832,61 @@
6163
5832
  end: dataOffset + compressedSize + dataDescriptorLength,
6164
5833
  fileEntry
6165
5834
  };
6166
- for (const [otherIndex, otherRange] of readRanges) {
6167
- if (otherIndex != index && range.start < otherRange.end && otherRange.start < range.end) {
5835
+ const { indexes, sortedRanges, pendingRanges } = readRanges;
5836
+ if (!indexes.has(index)) {
5837
+ const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
5838
+ if (overlappingRange) {
6168
5839
  const error = new Error(ERR_OVERLAPPING_ENTRY);
6169
- error.overlappingEntry = otherRange.fileEntry;
5840
+ error.overlappingEntry = overlappingRange.fileEntry;
6170
5841
  throw error;
6171
5842
  }
5843
+ indexes.add(index);
5844
+ pendingRanges.push(range);
5845
+ if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
5846
+ pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
5847
+ readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
5848
+ pendingRanges.length = 0;
5849
+ }
5850
+ }
5851
+ }
5852
+
5853
+ function findOverlappingRange(sortedRanges, range) {
5854
+ let low = 0;
5855
+ let high = sortedRanges.length;
5856
+ while (low < high) {
5857
+ const middle = (low + high) >>> 1;
5858
+ if (sortedRanges[middle].start < range.start) {
5859
+ low = middle + 1;
5860
+ } else {
5861
+ high = middle;
5862
+ }
5863
+ }
5864
+ const previousRange = sortedRanges[low - 1];
5865
+ const nextRange = sortedRanges[low];
5866
+ if (previousRange && rangesOverlap(range, previousRange)) {
5867
+ return previousRange;
5868
+ }
5869
+ if (nextRange && rangesOverlap(range, nextRange)) {
5870
+ return nextRange;
5871
+ }
5872
+ }
5873
+
5874
+ function rangesOverlap(range, otherRange) {
5875
+ return range.start < otherRange.end && otherRange.start < range.end;
5876
+ }
5877
+
5878
+ function mergeRanges(sortedRanges, pendingRanges) {
5879
+ const mergedRanges = [];
5880
+ let indexSorted = 0;
5881
+ let indexPending = 0;
5882
+ while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
5883
+ if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
5884
+ mergedRanges.push(sortedRanges[indexSorted++]);
5885
+ } else {
5886
+ mergedRanges.push(pendingRanges[indexPending++]);
5887
+ }
6172
5888
  }
6173
- readRanges.set(index, range);
5889
+ return mergedRanges;
6174
5890
  }
6175
5891
 
6176
5892
  function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
@@ -6748,7 +6464,6 @@
6748
6464
  rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
6749
6465
  rawExtraField,
6750
6466
  rawCentralExtraField: EMPTY_UINT8_ARRAY,
6751
- extendedTimestamp: false,
6752
6467
  headerArray,
6753
6468
  headerView
6754
6469
  });
@@ -7492,7 +7207,7 @@
7492
7207
  }
7493
7208
  }
7494
7209
  const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
7495
- if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7210
+ if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
7496
7211
  dataDescriptor = false;
7497
7212
  }
7498
7213
  const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
@@ -9102,7 +8817,7 @@
9102
8817
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9103
8818
  */
9104
8819
 
9105
- const VERSION = "2.13.1";
8820
+ const VERSION = "2.14.1";
9106
8821
 
9107
8822
  /*
9108
8823
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -10022,12 +9737,16 @@
10022
9737
  let directoryEntry = parent;
10023
9738
  if (name) {
10024
9739
  directoryEntry = parent.getChildByName(name);
10025
- if (directoryEntry && !directoryEntry.directory) {
9740
+ if (directoryEntry && (!directoryEntry.directory || directoryEntry.data)) {
10026
9741
  if (duplicates == DUPLICATES_KEEP_FIRST) {
10027
9742
  continue;
10028
9743
  } else if (duplicates == DUPLICATES_KEEP_LAST) {
10029
- this.fs.remove(directoryEntry);
10030
- directoryEntry = UNDEFINED_VALUE;
9744
+ if (directoryEntry.directory) {
9745
+ directoryEntry.data = entry;
9746
+ } else {
9747
+ this.fs.remove(directoryEntry);
9748
+ directoryEntry = UNDEFINED_VALUE;
9749
+ }
10031
9750
  } else {
10032
9751
  throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
10033
9752
  }