@zip.js/zip.js 2.7.47 → 2.7.49

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.
@@ -53,7 +53,7 @@ const PROPERTY_NAMES = [
53
53
  PROPERTY_NAME_MS_DOS_COMPATIBLE, PROPERTY_NAME_ZIP64,
54
54
  "directory", "bitFlag", "encrypted", "signature", "filenameUTF8", "commentUTF8", "compressionMethod", "version", "versionMadeBy",
55
55
  "extraField", "rawExtraField", "extraFieldZip64", "extraFieldUnicodePath", "extraFieldUnicodeComment", "extraFieldAES", "extraFieldNTFS",
56
- "extraFieldExtendedTimestamp"];
56
+ "extraFieldExtendedTimestamp", "zipCrypto"];
57
57
 
58
58
  class Entry {
59
59
 
@@ -72,7 +72,8 @@ class ZipEntry {
72
72
  id: fs.entries.length,
73
73
  parent,
74
74
  children: [],
75
- uncompressedSize: params.uncompressedSize || 0
75
+ uncompressedSize: params.uncompressedSize || 0,
76
+ passThrough: params.passThrough
76
77
  });
77
78
  fs.entries.push(zipEntry);
78
79
  if (parent) {
@@ -415,7 +416,8 @@ class ZipDirectoryEntry extends ZipEntry {
415
416
  importedEntries.push(addChild(parent, name, {
416
417
  data: entry,
417
418
  Reader: getZipBlobReader(Object.assign({}, options)),
418
- uncompressedSize: entry.uncompressedSize
419
+ uncompressedSize: entry.uncompressedSize,
420
+ passThrough: options.passThrough
419
421
  }));
420
422
  }
421
423
  } catch (error) {
@@ -732,8 +734,17 @@ async function exportZip(zipWriter, entry, totalSize, options) {
732
734
  comment,
733
735
  lastModDate,
734
736
  creationDate,
735
- lastAccessDate
737
+ lastAccessDate,
738
+ uncompressedSize,
739
+ encrypted,
740
+ zipCrypto,
741
+ signature,
742
+ compressionMethod
736
743
  } = child.data;
744
+ let level;
745
+ if (compressionMethod === 0) {
746
+ level = 0;
747
+ }
737
748
  zipEntryOptions = {
738
749
  externalFileAttribute,
739
750
  versionMadeBy,
@@ -742,6 +753,16 @@ async function exportZip(zipWriter, entry, totalSize, options) {
742
753
  creationDate,
743
754
  lastAccessDate
744
755
  };
756
+ if (child.passThrough) {
757
+ zipEntryOptions = Object.assign(zipEntryOptions, {
758
+ passThrough: true,
759
+ encrypted,
760
+ zipCrypto,
761
+ signature,
762
+ uncompressedSize,
763
+ level
764
+ });
765
+ }
745
766
  }
746
767
  await zipWriter.add(name, child.reader, Object.assign({
747
768
  directory: child.directory
@@ -294,6 +294,7 @@ class ZipReader {
294
294
  });
295
295
  startOffset = Math.max(offsetFileEntry, startOffset);
296
296
  await readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
297
+ fileEntry.zipCrypto = fileEntry.encrypted && !fileEntry.extraFieldAES;
297
298
  const entry = new Entry(fileEntry);
298
299
  entry.getData = (writer, options) => fileEntry.getData(writer, entry, options);
299
300
  offset = endOffset;
@@ -428,8 +429,12 @@ class ZipEntry {
428
429
  lastAccessDate: localDirectory.lastAccessDate,
429
430
  creationDate: localDirectory.creationDate
430
431
  });
431
- const encrypted = zipEntry.encrypted && localDirectory.encrypted;
432
+ const passThrough = getOptionValue(zipEntry, options, "passThrough");
433
+ const encrypted = zipEntry.encrypted && localDirectory.encrypted && !passThrough;
432
434
  const zipCrypto = encrypted && !extraFieldAES;
435
+ if (!passThrough) {
436
+ fileEntry.zipCrypto = zipCrypto;
437
+ }
433
438
  if (encrypted) {
434
439
  if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
435
440
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
@@ -461,11 +466,11 @@ class ZipEntry {
461
466
  rawPassword,
462
467
  zipCrypto,
463
468
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
464
- signed: getOptionValue(zipEntry, options, "checkSignature"),
469
+ signed: getOptionValue(zipEntry, options, "checkSignature") && !passThrough,
465
470
  passwordVerification: zipCrypto && (bitFlag.dataDescriptor ? ((rawLastModDate >>> 8) & 0xFF) : ((signature >>> 24) & 0xFF)),
466
471
  signature,
467
- compressed: compressionMethod != 0,
468
- encrypted,
472
+ compressed: compressionMethod != 0 && !passThrough,
473
+ encrypted: zipEntry.encrypted && !passThrough,
469
474
  useWebWorkers: getOptionValue(zipEntry, options, "useWebWorkers"),
470
475
  useCompressionStream: getOptionValue(zipEntry, options, "useCompressionStream"),
471
476
  transferStreams: getOptionValue(zipEntry, options, "transferStreams"),
@@ -98,6 +98,7 @@ const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
98
98
  const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
99
99
  const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
100
100
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
101
+ const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
101
102
 
102
103
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
103
104
 
@@ -118,7 +119,7 @@ class ZipWriter {
118
119
  config: getConfiguration(),
119
120
  files: new Map(),
120
121
  filenames: new Set(),
121
- offset: writer.writable.size,
122
+ offset: options.offset === UNDEFINED_VALUE ? writer.writable.size : options.offset,
122
123
  pendingEntriesSize: 0,
123
124
  pendingAddFileCalls: new Set(),
124
125
  bufferedWrites: 0
@@ -214,7 +215,8 @@ export {
214
215
  ERR_INVALID_EXTRAFIELD_TYPE,
215
216
  ERR_INVALID_EXTRAFIELD_DATA,
216
217
  ERR_INVALID_ENCRYPTION_STRENGTH,
217
- ERR_UNSUPPORTED_FORMAT
218
+ ERR_UNSUPPORTED_FORMAT,
219
+ ERR_UNDEFINED_UNCOMPRESSED_SIZE
218
220
  };
219
221
 
220
222
  async function addFile(zipWriter, name, reader, options) {
@@ -254,8 +256,12 @@ async function addFile(zipWriter, name, reader, options) {
254
256
  const msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE, true);
255
257
  const internalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, 0);
256
258
  const externalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE, 0);
257
- const password = getOptionValue(zipWriter, options, "password");
258
- const rawPassword = getOptionValue(zipWriter, options, "rawPassword");
259
+ const passThrough = getOptionValue(zipWriter, options, "passThrough");
260
+ let password, rawPassword;
261
+ if (!passThrough) {
262
+ password = getOptionValue(zipWriter, options, "password");
263
+ rawPassword = getOptionValue(zipWriter, options, "rawPassword");
264
+ }
259
265
  const encryptionStrength = getOptionValue(zipWriter, options, "encryptionStrength", 3);
260
266
  const zipCrypto = getOptionValue(zipWriter, options, "zipCrypto");
261
267
  const extendedTimestamp = getOptionValue(zipWriter, options, "extendedTimestamp", true);
@@ -265,10 +271,11 @@ async function addFile(zipWriter, name, reader, options) {
265
271
  const bufferedWrite = getOptionValue(zipWriter, options, "bufferedWrite");
266
272
  const dataDescriptorSignature = getOptionValue(zipWriter, options, "dataDescriptorSignature", false);
267
273
  const signal = getOptionValue(zipWriter, options, "signal");
274
+ const useUnicodeFileNames = getOptionValue(zipWriter, options, "useUnicodeFileNames", true);
268
275
  const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
269
276
  let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor", true);
270
277
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
271
- if (password !== UNDEFINED_VALUE && encryptionStrength !== UNDEFINED_VALUE && (encryptionStrength < 1 || encryptionStrength > 3)) {
278
+ if ((password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && encryptionStrength !== UNDEFINED_VALUE && (encryptionStrength < 1 || encryptionStrength > 3)) {
272
279
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
273
280
  }
274
281
  let rawExtraField = new Uint8Array();
@@ -294,18 +301,28 @@ async function addFile(zipWriter, name, reader, options) {
294
301
  let maximumCompressedSize = 0;
295
302
  let maximumEntrySize = 0;
296
303
  let uncompressedSize = 0;
304
+ if (passThrough) {
305
+ ({ uncompressedSize } = options);
306
+ if (uncompressedSize === UNDEFINED_VALUE) {
307
+ throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
308
+ }
309
+ }
297
310
  const zip64Enabled = zip64 === true;
298
311
  if (reader) {
299
312
  reader = initReader(reader);
300
313
  await initStream(reader);
301
- if (reader.size === UNDEFINED_VALUE) {
302
- dataDescriptor = true;
303
- if (zip64 || zip64 === UNDEFINED_VALUE) {
304
- zip64 = true;
305
- uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
314
+ if (!passThrough) {
315
+ if (reader.size === UNDEFINED_VALUE) {
316
+ dataDescriptor = true;
317
+ if (zip64 || zip64 === UNDEFINED_VALUE) {
318
+ zip64 = true;
319
+ uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
320
+ }
321
+ } else {
322
+ uncompressedSize = reader.size;
323
+ maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
306
324
  }
307
325
  } else {
308
- uncompressedSize = reader.size;
309
326
  maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
310
327
  }
311
328
  }
@@ -323,6 +340,8 @@ async function addFile(zipWriter, name, reader, options) {
323
340
  }
324
341
  }
325
342
  zip64 = zip64 || false;
343
+ const encrypted = getOptionValue(zipWriter, options, "encrypted");
344
+ const { signature } = options;
326
345
  options = Object.assign({}, options, {
327
346
  rawFilename,
328
347
  rawComment,
@@ -346,13 +365,17 @@ async function addFile(zipWriter, name, reader, options) {
346
365
  zipCrypto,
347
366
  bufferedWrite,
348
367
  keepOrder,
368
+ useUnicodeFileNames,
349
369
  dataDescriptor,
350
370
  dataDescriptorSignature,
351
371
  signal,
352
372
  msDosCompatible,
353
373
  internalFileAttribute,
354
374
  externalFileAttribute,
355
- useCompressionStream
375
+ useCompressionStream,
376
+ passThrough,
377
+ encrypted: Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted),
378
+ signature
356
379
  });
357
380
  const headerInfo = getHeaderInfo(options);
358
381
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -563,7 +586,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
563
586
  msDosCompatible,
564
587
  internalFileAttribute,
565
588
  externalFileAttribute,
566
- useCompressionStream
589
+ useCompressionStream,
590
+ passThrough
567
591
  } = options;
568
592
  const fileEntry = {
569
593
  lock,
@@ -584,9 +608,14 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
584
608
  externalFileAttribute,
585
609
  diskNumberStart
586
610
  };
611
+ let {
612
+ signature,
613
+ uncompressedSize
614
+ } = options;
587
615
  let compressedSize = 0;
588
- let uncompressedSize = 0;
589
- let signature;
616
+ if (!passThrough) {
617
+ uncompressedSize = 0;
618
+ }
590
619
  const { writable } = writer;
591
620
  if (reader) {
592
621
  reader.chunkSize = getChunkSize(config);
@@ -602,9 +631,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
602
631
  encryptionStrength,
603
632
  zipCrypto: encrypted && zipCrypto,
604
633
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & 0xFF,
605
- signed: true,
606
- compressed,
607
- encrypted,
634
+ signed: !passThrough,
635
+ compressed: compressed && !passThrough,
636
+ encrypted: encrypted && !passThrough,
608
637
  useWebWorkers,
609
638
  useCompressionStream,
610
639
  transferStreams: false
@@ -613,9 +642,11 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
613
642
  streamOptions: { signal, size, onstart, onprogress, onend }
614
643
  };
615
644
  const result = await runWorker({ readable, writable }, workerOptions);
616
- uncompressedSize = result.inputSize;
617
645
  compressedSize = result.outputSize;
618
- signature = result.signature;
646
+ if (!passThrough) {
647
+ uncompressedSize = result.inputSize;
648
+ signature = result.signature;
649
+ }
619
650
  writable.size += uncompressedSize;
620
651
  } else {
621
652
  await writeData(writable, localHeaderArray);
@@ -658,6 +689,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
658
689
  creationDate,
659
690
  lastAccessDate,
660
691
  encrypted,
692
+ zipCrypto,
661
693
  size: metadataSize + compressedSize,
662
694
  compressionMethod,
663
695
  version,
@@ -679,19 +711,18 @@ function getHeaderInfo(options) {
679
711
  lastModDate,
680
712
  lastAccessDate,
681
713
  creationDate,
682
- rawPassword,
683
- password,
684
714
  level,
685
715
  zip64,
686
716
  zipCrypto,
717
+ useUnicodeFileNames,
687
718
  dataDescriptor,
688
719
  directory,
689
720
  rawExtraField,
690
721
  encryptionStrength,
691
- extendedTimestamp
722
+ extendedTimestamp,
723
+ encrypted
692
724
  } = options;
693
725
  const compressed = level !== 0 && !directory;
694
- const encrypted = Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword)));
695
726
  let version = options.version;
696
727
  let rawExtraFieldAES;
697
728
  if (encrypted && !zipCrypto) {
@@ -740,13 +771,25 @@ function getHeaderInfo(options) {
740
771
  } else {
741
772
  rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
742
773
  }
743
- let bitFlag = BITFLAG_LANG_ENCODING_FLAG;
774
+ let bitFlag = 0;
775
+ if (useUnicodeFileNames) {
776
+ bitFlag = bitFlag | BITFLAG_LANG_ENCODING_FLAG;
777
+ }
744
778
  if (dataDescriptor) {
745
779
  bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
746
780
  }
747
781
  let compressionMethod = COMPRESSION_METHOD_STORE;
748
782
  if (compressed) {
749
783
  compressionMethod = COMPRESSION_METHOD_DEFLATE;
784
+ if (level >= 1 && level < 3) {
785
+ bitFlag = bitFlag | 0b110;
786
+ }
787
+ if (level >= 3 && level < 5) {
788
+ bitFlag = bitFlag | 0b01;
789
+ }
790
+ if (level === 9) {
791
+ bitFlag = bitFlag | 0b10;
792
+ }
750
793
  }
751
794
  if (zip64) {
752
795
  version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A JavaScript library to zip and unzip files in the browser, Deno and Node.js",
4
4
  "author": "Gildas Lormeau",
5
5
  "license": "BSD-3-Clause",
6
- "version": "2.7.47",
6
+ "version": "2.7.49",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",
@@ -80,7 +80,7 @@
80
80
  "@rollup/plugin-replace": "^5.0.7",
81
81
  "@rollup/plugin-terser": "^0.4.4",
82
82
  "http-server": "^14.1.1",
83
- "rollup": "^4.18.1",
84
- "typedoc": "^0.26.4"
83
+ "rollup": "^4.21.0",
84
+ "typedoc": "^0.26.6"
85
85
  }
86
86
  }