@zip.js/zip.js 2.8.7 → 2.8.8

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.
@@ -36,6 +36,7 @@
36
36
 
37
37
  const MAX_32_BITS = 0xffffffff;
38
38
  const MAX_16_BITS = 0xffff;
39
+ const MAX_8_BITS = 0xff;
39
40
  const COMPRESSION_METHOD_DEFLATE = 0x08;
40
41
  const COMPRESSION_METHOD_DEFLATE_64 = 0x09;
41
42
  const COMPRESSION_METHOD_STORE = 0x00;
@@ -65,6 +66,8 @@
65
66
  const EXTRAFIELD_TYPE_UNICODE_PATH = 0x7075;
66
67
  const EXTRAFIELD_TYPE_UNICODE_COMMENT = 0x6375;
67
68
  const EXTRAFIELD_TYPE_USDZ = 0x1986;
69
+ const EXTRAFIELD_TYPE_INFOZIP = 0x7875;
70
+ const EXTRAFIELD_TYPE_UNIX = 0x7855;
68
71
 
69
72
  const BITFLAG_ENCRYPTED = 0b1;
70
73
  const BITFLAG_LEVEL = 0b0110;
@@ -74,10 +77,17 @@
74
77
  const BITFLAG_DATA_DESCRIPTOR = 0b1000;
75
78
  const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
76
79
  const FILE_ATTR_MSDOS_DIR_MASK = 0b10000;
80
+ const FILE_ATTR_MSDOS_READONLY_MASK = 0x01;
81
+ const FILE_ATTR_MSDOS_HIDDEN_MASK = 0x02;
82
+ const FILE_ATTR_MSDOS_SYSTEM_MASK = 0x04;
83
+ const FILE_ATTR_MSDOS_ARCHIVE_MASK = 0x20;
77
84
  const FILE_ATTR_UNIX_TYPE_MASK = 0o170000;
78
85
  const FILE_ATTR_UNIX_TYPE_DIR = 0o040000;
79
86
  const FILE_ATTR_UNIX_EXECUTABLE_MASK = 0o111;
80
87
  const FILE_ATTR_UNIX_DEFAULT_MASK = 0o644;
88
+ const FILE_ATTR_UNIX_SETUID_MASK = 0o4000;
89
+ const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
90
+ const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
81
91
 
82
92
  const VERSION_DEFLATE = 0x14;
83
93
  const VERSION_ZIP64 = 0x2D;
@@ -96,6 +106,7 @@
96
106
  const UNDEFINED_VALUE = undefined;
97
107
  const UNDEFINED_TYPE = "undefined";
98
108
  const FUNCTION_TYPE = "function";
109
+ const OBJECT_TYPE = "object";
99
110
 
100
111
  /*
101
112
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -201,6 +212,7 @@
201
212
  const HTTP_METHOD_GET = "GET";
202
213
  const HTTP_RANGE_UNIT = "bytes";
203
214
  const DEFAULT_CHUNK_SIZE = 64 * 1024;
215
+ const DEFAULT_BUFFER_SIZE = 256 * 1024;
204
216
 
205
217
  const PROPERTY_NAME_WRITABLE = "writable";
206
218
 
@@ -685,19 +697,29 @@
685
697
 
686
698
  class Uint8ArrayWriter extends Writer {
687
699
 
700
+ constructor(defaultBufferSize) {
701
+ super();
702
+ this.defaultBufferSize = defaultBufferSize || DEFAULT_BUFFER_SIZE;
703
+ }
704
+
688
705
  init(initSize = 0) {
689
706
  Object.assign(this, {
690
707
  offset: 0,
691
- array: new Uint8Array(initSize)
708
+ array: new Uint8Array(initSize > 0 ? initSize : this.defaultBufferSize)
692
709
  });
693
710
  super.init();
694
711
  }
695
712
 
696
713
  writeUint8Array(array) {
697
714
  const writer = this;
698
- if (writer.offset + array.length > writer.array.length) {
715
+ const requiredLength = writer.offset + array.length;
716
+ if (requiredLength > writer.array.length) {
717
+ let newLength = writer.array.length ? writer.array.length * 2 : writer.defaultBufferSize;
718
+ while (newLength < requiredLength) {
719
+ newLength *= 2;
720
+ }
699
721
  const previousArray = writer.array;
700
- writer.array = new Uint8Array(previousArray.length + array.length);
722
+ writer.array = new Uint8Array(newLength);
701
723
  writer.array.set(previousArray);
702
724
  }
703
725
  writer.array.set(array, writer.offset);
@@ -705,7 +727,11 @@
705
727
  }
706
728
 
707
729
  getData() {
708
- return this.array;
730
+ if (this.offset === this.array.length) {
731
+ return this.array;
732
+ } else {
733
+ return this.array.slice(0, this.offset);
734
+ }
709
735
  }
710
736
  }
711
737
 
@@ -3194,6 +3220,8 @@
3194
3220
  const PROPERTY_NAME_RAW_CREATION_DATE = "rawCreationDate";
3195
3221
  const PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES = "internalFileAttributes";
3196
3222
  const PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES = "externalFileAttributes";
3223
+ const PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW = "msdosAttributesRaw";
3224
+ const PROPERTY_NAME_MSDOS_ATTRIBUTES = "msdosAttributes";
3197
3225
  const PROPERTY_NAME_MS_DOS_COMPATIBLE = "msDosCompatible";
3198
3226
  const PROPERTY_NAME_ZIP64 = "zip64";
3199
3227
  const PROPERTY_NAME_ENCRYPTED = "encrypted";
@@ -3205,17 +3233,73 @@
3205
3233
  const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
3206
3234
  const PROPERTY_NAME_SIGNATURE = "signature";
3207
3235
  const PROPERTY_NAME_EXTRA_FIELD = "extraField";
3236
+ const PROPERTY_NAME_EXTRA_FIELD_INFOZIP = "extraFieldInfoZip";
3237
+ const PROPERTY_NAME_EXTRA_FIELD_UNIX = "extraFieldUnix";
3238
+ const PROPERTY_NAME_UID = "uid";
3239
+ const PROPERTY_NAME_GID = "gid";
3240
+ const PROPERTY_NAME_UNIX_MODE = "unixMode";
3241
+ const PROPERTY_NAME_SETUID = "setuid";
3242
+ const PROPERTY_NAME_SETGID = "setgid";
3243
+ const PROPERTY_NAME_STICKY = "sticky";
3244
+ const PROPERTY_NAME_BITFLAG = "bitFlag";
3245
+ const PROPERTY_NAME_FILENAME_UTF8 = "filenameUTF8";
3246
+ const PROPERTY_NAME_COMMENT_UTF8 = "commentUTF8";
3247
+ const PROPERTY_NAME_RAW_EXTRA_FIELD = "rawExtraField";
3248
+ const PROPERTY_NAME_EXTRA_FIELD_ZIP64 = "extraFieldZip64";
3249
+ const PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH = "extraFieldUnicodePath";
3250
+ const PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT = "extraFieldUnicodeComment";
3251
+ const PROPERTY_NAME_EXTRA_FIELD_AES = "extraFieldAES";
3252
+ const PROPERTY_NAME_EXTRA_FIELD_NTFS = "extraFieldNTFS";
3253
+ const PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP = "extraFieldExtendedTimestamp";
3208
3254
 
3209
3255
  const PROPERTY_NAMES = [
3210
- PROPERTY_NAME_FILENAME, PROPERTY_NAME_RAW_FILENAME, PROPERTY_NAME_COMPRESSED_SIZE, PROPERTY_NAME_UNCOMPRESSED_SIZE,
3211
- PROPERTY_NAME_LAST_MODIFICATION_DATE, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE, PROPERTY_NAME_COMMENT, PROPERTY_NAME_RAW_COMMENT,
3212
- PROPERTY_NAME_LAST_ACCESS_DATE, PROPERTY_NAME_CREATION_DATE, PROPERTY_NAME_OFFSET, PROPERTY_NAME_DISK_NUMBER_START,
3213
- PROPERTY_NAME_DISK_NUMBER_START, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
3214
- PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_MS_DOS_COMPATIBLE, PROPERTY_NAME_ZIP64,
3215
- PROPERTY_NAME_ENCRYPTED, PROPERTY_NAME_VERSION, PROPERTY_NAME_VERSION_MADE_BY, PROPERTY_NAME_ZIPCRYPTO, PROPERTY_NAME_DIRECTORY,
3216
- PROPERTY_NAME_EXECUTABLE, PROPERTY_NAME_COMPRESSION_METHOD, PROPERTY_NAME_SIGNATURE, PROPERTY_NAME_EXTRA_FIELD,
3217
- "bitFlag", "filenameUTF8", "commentUTF8", "rawExtraField", "extraFieldZip64", "extraFieldUnicodePath", "extraFieldUnicodeComment",
3218
- "extraFieldAES", "extraFieldNTFS", "extraFieldExtendedTimestamp"];
3256
+ PROPERTY_NAME_FILENAME,
3257
+ PROPERTY_NAME_RAW_FILENAME,
3258
+ PROPERTY_NAME_UNCOMPRESSED_SIZE,
3259
+ PROPERTY_NAME_COMPRESSED_SIZE,
3260
+ PROPERTY_NAME_LAST_MODIFICATION_DATE,
3261
+ PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE,
3262
+ PROPERTY_NAME_COMMENT,
3263
+ PROPERTY_NAME_RAW_COMMENT,
3264
+ PROPERTY_NAME_LAST_ACCESS_DATE,
3265
+ PROPERTY_NAME_CREATION_DATE,
3266
+ PROPERTY_NAME_RAW_CREATION_DATE,
3267
+ PROPERTY_NAME_OFFSET,
3268
+ PROPERTY_NAME_DISK_NUMBER_START,
3269
+ PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
3270
+ PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
3271
+ PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW,
3272
+ PROPERTY_NAME_MSDOS_ATTRIBUTES,
3273
+ PROPERTY_NAME_MS_DOS_COMPATIBLE,
3274
+ PROPERTY_NAME_ZIP64,
3275
+ PROPERTY_NAME_ENCRYPTED,
3276
+ PROPERTY_NAME_VERSION,
3277
+ PROPERTY_NAME_VERSION_MADE_BY,
3278
+ PROPERTY_NAME_ZIPCRYPTO,
3279
+ PROPERTY_NAME_DIRECTORY,
3280
+ PROPERTY_NAME_EXECUTABLE,
3281
+ PROPERTY_NAME_COMPRESSION_METHOD,
3282
+ PROPERTY_NAME_SIGNATURE,
3283
+ PROPERTY_NAME_EXTRA_FIELD,
3284
+ PROPERTY_NAME_EXTRA_FIELD_UNIX,
3285
+ PROPERTY_NAME_EXTRA_FIELD_INFOZIP,
3286
+ PROPERTY_NAME_UID,
3287
+ PROPERTY_NAME_GID,
3288
+ PROPERTY_NAME_UNIX_MODE,
3289
+ PROPERTY_NAME_SETUID,
3290
+ PROPERTY_NAME_SETGID,
3291
+ PROPERTY_NAME_STICKY,
3292
+ PROPERTY_NAME_BITFLAG,
3293
+ PROPERTY_NAME_FILENAME_UTF8,
3294
+ PROPERTY_NAME_COMMENT_UTF8,
3295
+ PROPERTY_NAME_RAW_EXTRA_FIELD,
3296
+ PROPERTY_NAME_EXTRA_FIELD_ZIP64,
3297
+ PROPERTY_NAME_EXTRA_FIELD_UNICODE_PATH,
3298
+ PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT,
3299
+ PROPERTY_NAME_EXTRA_FIELD_AES,
3300
+ PROPERTY_NAME_EXTRA_FIELD_NTFS,
3301
+ PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP
3302
+ ];
3219
3303
 
3220
3304
  class Entry {
3221
3305
 
@@ -3282,6 +3366,7 @@
3282
3366
  const OPTION_ENCODE_TEXT = "encodeText";
3283
3367
  const OPTION_OFFSET = "offset";
3284
3368
  const OPTION_USDZ = "usdz";
3369
+ const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
3285
3370
 
3286
3371
  /*
3287
3372
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -3324,6 +3409,7 @@
3324
3409
  const ERR_SPLIT_ZIP_FILE = "Split zip file";
3325
3410
  const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
3326
3411
  const CHARSET_UTF8 = "utf-8";
3412
+ const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
3327
3413
  const CHARSET_CP437 = "cp437";
3328
3414
  const ZIP64_PROPERTIES = [
3329
3415
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
@@ -3479,51 +3565,71 @@
3479
3565
  const filenameUTF8 = languageEncodingFlag;
3480
3566
  const commentUTF8 = languageEncodingFlag;
3481
3567
  const externalFileAttributes = getUint32(directoryView, offset + 38);
3482
- const directory =
3483
- (msDosCompatible && ((getUint8(directoryView, offset + 38) & FILE_ATTR_MSDOS_DIR_MASK) == FILE_ATTR_MSDOS_DIR_MASK)) ||
3484
- (unixCompatible && (((externalFileAttributes >> 16) & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR)) ||
3485
- (rawFilename.length && rawFilename.at(-1) == DIRECTORY_SIGNATURE.charCodeAt(0));
3486
- const executable = (unixCompatible && (((externalFileAttributes >> 16) & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
3568
+ const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
3569
+ const msdosAttributes = {
3570
+ readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
3571
+ hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK),
3572
+ system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK),
3573
+ directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
3574
+ archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
3575
+ };
3487
3576
  const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength;
3577
+ const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
3578
+ const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
3579
+ const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
3580
+ let filename = decode(rawFilename, rawFilenameEncoding);
3581
+ if (filename === UNDEFINED_VALUE) {
3582
+ filename = decodeText(rawFilename, rawFilenameEncoding);
3583
+ }
3584
+ let comment = decode(rawComment, rawCommentEncoding);
3585
+ if (comment === UNDEFINED_VALUE) {
3586
+ comment = decodeText(rawComment, rawCommentEncoding);
3587
+ }
3488
3588
  Object.assign(fileEntry, {
3489
3589
  versionMadeBy,
3490
3590
  msDosCompatible,
3491
3591
  compressedSize: 0,
3492
3592
  uncompressedSize: 0,
3493
3593
  commentLength,
3494
- directory,
3495
3594
  offset: offsetFileEntry,
3496
3595
  diskNumberStart: getUint16(directoryView, offset + 34),
3497
3596
  internalFileAttributes: getUint16(directoryView, offset + 36),
3498
3597
  externalFileAttributes,
3598
+ msdosAttributesRaw,
3599
+ msdosAttributes,
3499
3600
  rawFilename,
3500
3601
  filenameUTF8,
3501
3602
  commentUTF8,
3502
3603
  rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset),
3503
- executable
3504
- });
3505
- fileEntry.internalFileAttribute = fileEntry.internalFileAttributes;
3506
- fileEntry.externalFileAttribute = fileEntry.externalFileAttributes;
3507
- const decode = getOptionValue$1(zipReader, options, OPTION_DECODE_TEXT) || decodeText;
3508
- const rawFilenameEncoding = filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437;
3509
- const rawCommentEncoding = commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437;
3510
- let filename = decode(rawFilename, rawFilenameEncoding);
3511
- if (filename === UNDEFINED_VALUE) {
3512
- filename = decodeText(rawFilename, rawFilenameEncoding);
3513
- }
3514
- let comment = decode(rawComment, rawCommentEncoding);
3515
- if (comment === UNDEFINED_VALUE) {
3516
- comment = decodeText(rawComment, rawCommentEncoding);
3517
- }
3518
- Object.assign(fileEntry, {
3519
3604
  rawComment,
3520
3605
  filename,
3521
- comment,
3522
- directory: directory || filename.endsWith(DIRECTORY_SIGNATURE)
3606
+ comment
3523
3607
  });
3524
3608
  startOffset = Math.max(offsetFileEntry, startOffset);
3525
3609
  readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
3526
- fileEntry.zipCrypto = fileEntry.encrypted && !fileEntry.extraFieldAES;
3610
+ const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
3611
+ if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
3612
+ fileEntry.unixMode = unixExternalUpper;
3613
+ }
3614
+ const setuid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETUID_MASK);
3615
+ const setgid = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_SETGID_MASK);
3616
+ const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
3617
+ const executable = (fileEntry.unixMode !== UNDEFINED_VALUE)
3618
+ ? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
3619
+ : (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0));
3620
+ const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
3621
+ const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
3622
+ Object.assign(fileEntry, {
3623
+ setuid,
3624
+ setgid,
3625
+ sticky,
3626
+ unixExternalUpper,
3627
+ internalFileAttribute: fileEntry.internalFileAttributes,
3628
+ externalFileAttribute: fileEntry.externalFileAttributes,
3629
+ executable,
3630
+ directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || (filename.endsWith(DIRECTORY_SIGNATURE) && !fileEntry.uncompressedSize),
3631
+ zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
3632
+ });
3527
3633
  const entry = new Entry(fileEntry);
3528
3634
  entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader.readRanges, options);
3529
3635
  entry.arrayBuffer = async options => {
@@ -3669,7 +3775,7 @@
3669
3775
  zipCrypto,
3670
3776
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
3671
3777
  signed: getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) && !passThrough,
3672
- passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & 0xFF) : ((signature >>> 24) & 0xFF)),
3778
+ passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((signature >>> 24) & MAX_8_BITS)),
3673
3779
  outputSize: passThrough ? compressedSize : uncompressedSize,
3674
3780
  signature,
3675
3781
  compressed: compressionMethod != 0 && !passThrough,
@@ -3800,6 +3906,17 @@
3800
3906
  readExtraFieldNTFS(extraFieldNTFS, directory);
3801
3907
  directory.extraFieldNTFS = extraFieldNTFS;
3802
3908
  }
3909
+ const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
3910
+ if (extraFieldUnix) {
3911
+ readExtraFieldUnix(extraFieldUnix, directory, false);
3912
+ directory.extraFieldUnix = extraFieldUnix;
3913
+ } else {
3914
+ const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
3915
+ if (extraFieldInfoZip) {
3916
+ readExtraFieldUnix(extraFieldInfoZip, directory, true);
3917
+ directory.extraFieldInfoZip = extraFieldInfoZip;
3918
+ }
3919
+ }
3803
3920
  const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
3804
3921
  if (extraFieldExtendedTimestamp) {
3805
3922
  readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
@@ -3841,7 +3958,7 @@
3841
3958
  });
3842
3959
  if (extraFieldUnicode.valid) {
3843
3960
  directory[propertyName] = extraFieldUnicode[propertyName];
3844
- directory[propertyName + "UTF8"] = true;
3961
+ directory[propertyName + PROPERTY_NAME_UTF8_SUFFIX] = true;
3845
3962
  }
3846
3963
  }
3847
3964
 
@@ -3897,6 +4014,47 @@
3897
4014
  }
3898
4015
  }
3899
4016
 
4017
+ function readExtraFieldUnix(extraField, directory, isInfoZip) {
4018
+ try {
4019
+ const view = getDataView$1(new Uint8Array(extraField.data));
4020
+ let offset = 0;
4021
+ const version = getUint8(view, offset++);
4022
+ const uidSize = getUint8(view, offset++);
4023
+ const uidBytes = extraField.data.subarray(offset, offset + uidSize);
4024
+ offset += uidSize;
4025
+ const uid = unpackUnixId(uidBytes);
4026
+ const gidSize = getUint8(view, offset++);
4027
+ const gidBytes = extraField.data.subarray(offset, offset + gidSize);
4028
+ offset += gidSize;
4029
+ const gid = unpackUnixId(gidBytes);
4030
+ let unixMode = UNDEFINED_VALUE;
4031
+ if (!isInfoZip && offset + 2 <= extraField.data.length) {
4032
+ const base = extraField.data;
4033
+ const modeView = new DataView(base.buffer, base.byteOffset + offset, 2);
4034
+ unixMode = modeView.getUint16(0, true);
4035
+ }
4036
+ Object.assign(extraField, { version, uid, gid, unixMode });
4037
+ if (uid !== UNDEFINED_VALUE) {
4038
+ directory.uid = uid;
4039
+ }
4040
+ if (gid !== UNDEFINED_VALUE) {
4041
+ directory.gid = gid;
4042
+ }
4043
+ if (unixMode !== UNDEFINED_VALUE) {
4044
+ directory.unixMode = unixMode;
4045
+ }
4046
+ } catch {
4047
+ // ignored
4048
+ }
4049
+ }
4050
+
4051
+ function unpackUnixId(bytes) {
4052
+ const buffer = new Uint8Array(4);
4053
+ buffer.set(bytes, 0);
4054
+ const view = new DataView(buffer.buffer, buffer.byteOffset, 4);
4055
+ return view.getUint32(0, true);
4056
+ }
4057
+
3900
4058
  function readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory) {
3901
4059
  const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data);
3902
4060
  const flags = getUint8(extraFieldView, 0);
@@ -4023,7 +4181,7 @@
4023
4181
  }
4024
4182
 
4025
4183
  function getDate(timeRaw) {
4026
- const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
4184
+ const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
4027
4185
  try {
4028
4186
  return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
4029
4187
  } catch {
@@ -4099,8 +4257,16 @@
4099
4257
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
4100
4258
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
4101
4259
  const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
4260
+ const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
4261
+ const ERR_INVALID_GID = "Invalid gid (must be integer 0..2^32-1)";
4262
+ const ERR_INVALID_UNIX_MODE = "Invalid UNIX mode (must be integer 0..65535)";
4263
+ const ERR_INVALID_UNIX_EXTRA_FIELD_TYPE = "Invalid unixExtraFieldType (must be 'infozip' or 'unix')";
4264
+ const ERR_INVALID_MSDOS_ATTRIBUTES = "Invalid msdosAttributesRaw (must be integer 0..255)";
4265
+ const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
4102
4266
 
4103
4267
  const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
4268
+ const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
4269
+ const UNIX_EXTRA_FIELD_TYPE = "unix";
4104
4270
 
4105
4271
  let workers = 0;
4106
4272
  const pendingEntries = [];
@@ -4158,15 +4324,17 @@
4158
4324
  rawExtraFieldAES,
4159
4325
  rawExtraFieldExtendedTimestamp,
4160
4326
  rawExtraFieldNTFS,
4161
- rawExtraField
4327
+ rawExtraFieldUnix,
4328
+ rawExtraField,
4162
4329
  } = entry;
4163
4330
  const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
4164
4331
  rawExtraFieldZip64 = rawExtraFieldZip64 || new Uint8Array();
4165
4332
  rawExtraFieldAES = rawExtraFieldAES || new Uint8Array();
4166
4333
  rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || new Uint8Array();
4167
4334
  rawExtraFieldNTFS = rawExtraFieldNTFS || new Uint8Array();
4335
+ rawExtraFieldUnix = entry.rawExtraFieldUnix || new Uint8Array();
4168
4336
  rawExtraField = rawExtraField || new Uint8Array();
4169
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
4337
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
4170
4338
  const zip64UncompressedSize = zip64 && uncompressedSize > MAX_32_BITS;
4171
4339
  const zip64CompressedSize = zip64 && compressedSize > MAX_32_BITS;
4172
4340
  const {
@@ -4193,6 +4361,7 @@
4193
4361
  rawExtraFieldAES,
4194
4362
  rawExtraFieldExtendedTimestamp,
4195
4363
  rawExtraFieldNTFS,
4364
+ rawExtraFieldUnix,
4196
4365
  rawExtraField,
4197
4366
  extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
4198
4367
  extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
@@ -4261,7 +4430,7 @@
4261
4430
  while (pendingAddFileCalls.size) {
4262
4431
  await Promise.allSettled(Array.from(pendingAddFileCalls));
4263
4432
  }
4264
- await closeFile(this, comment, options);
4433
+ await closeFile(zipWriter, comment, options);
4265
4434
  const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
4266
4435
  if (!preventClose) {
4267
4436
  await writable.getWriter().close();
@@ -4272,9 +4441,45 @@
4272
4441
 
4273
4442
  async function addFile(zipWriter, name, reader, options) {
4274
4443
  name = name.trim();
4275
- const msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
4276
- const versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
4444
+ let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
4445
+ let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? 20 : 768);
4277
4446
  const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
4447
+ const uid = getOptionValue(zipWriter, options, PROPERTY_NAME_UID);
4448
+ const gid = getOptionValue(zipWriter, options, PROPERTY_NAME_GID);
4449
+ let unixMode = getOptionValue(zipWriter, options, PROPERTY_NAME_UNIX_MODE);
4450
+ const unixExtraFieldType = getOptionValue(zipWriter, options, OPTION_UNIX_EXTRA_FIELD_TYPE);
4451
+ let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
4452
+ let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
4453
+ let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
4454
+ if (uid !== UNDEFINED_VALUE && (uid < 0 || uid > MAX_32_BITS)) {
4455
+ throw new Error(ERR_INVALID_UID);
4456
+ }
4457
+ if (gid !== UNDEFINED_VALUE && (gid < 0 || gid > MAX_32_BITS)) {
4458
+ throw new Error(ERR_INVALID_GID);
4459
+ }
4460
+ if (unixMode !== UNDEFINED_VALUE && (unixMode < 0 || unixMode > MAX_16_BITS)) {
4461
+ throw new Error(ERR_INVALID_UNIX_MODE);
4462
+ }
4463
+ if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
4464
+ throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
4465
+ }
4466
+ let msdosAttributesRaw = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES_RAW);
4467
+ let msdosAttributes = getOptionValue(zipWriter, options, PROPERTY_NAME_MSDOS_ATTRIBUTES);
4468
+ const hasUnixMetadata = uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE || unixExtraFieldType;
4469
+ const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
4470
+ if (hasUnixMetadata) {
4471
+ msDosCompatible = false;
4472
+ versionMadeBy = (versionMadeBy & MAX_16_BITS) | (3 << 8);
4473
+ } else if (hasMsDosProvided) {
4474
+ msDosCompatible = true;
4475
+ versionMadeBy = (versionMadeBy & MAX_8_BITS);
4476
+ }
4477
+ if (msdosAttributesRaw !== UNDEFINED_VALUE && (msdosAttributesRaw < 0 || msdosAttributesRaw > MAX_8_BITS)) {
4478
+ throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
4479
+ }
4480
+ if (msdosAttributes && typeof msdosAttributes !== OBJECT_TYPE) {
4481
+ throw new Error(ERR_INVALID_MSDOS_DATA);
4482
+ }
4278
4483
  if (versionMadeBy > MAX_16_BITS) {
4279
4484
  throw new Error(ERR_INVALID_VERSION);
4280
4485
  }
@@ -4300,6 +4505,34 @@
4300
4505
  externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
4301
4506
  }
4302
4507
  }
4508
+ let unixExternalUpper;
4509
+ if (!msDosCompatible) {
4510
+ unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
4511
+ unixMode = unixMode === UNDEFINED_VALUE ? unixExternalUpper : (unixMode & MAX_16_BITS);
4512
+ if (setuid) {
4513
+ unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
4514
+ } else {
4515
+ setuid = Boolean(unixMode & FILE_ATTR_UNIX_SETUID_MASK);
4516
+ }
4517
+ if (setgid) {
4518
+ unixMode |= FILE_ATTR_UNIX_SETGID_MASK;
4519
+ } else {
4520
+ setgid = Boolean(unixMode & FILE_ATTR_UNIX_SETGID_MASK);
4521
+ }
4522
+ if (sticky) {
4523
+ unixMode |= FILE_ATTR_UNIX_STICKY_MASK;
4524
+ } else {
4525
+ sticky = Boolean(unixMode & FILE_ATTR_UNIX_STICKY_MASK);
4526
+ }
4527
+ if (directory) {
4528
+ unixMode |= FILE_ATTR_UNIX_TYPE_DIR;
4529
+ }
4530
+ externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_8_BITS);
4531
+ }
4532
+ ({ msdosAttributesRaw, msdosAttributes } = normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes));
4533
+ if (hasMsDosProvided) {
4534
+ externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
4535
+ }
4303
4536
  const encode = getOptionValue(zipWriter, options, OPTION_ENCODE_TEXT, encodeText);
4304
4537
  let rawFilename = encode(name);
4305
4538
  if (rawFilename === UNDEFINED_VALUE) {
@@ -4462,7 +4695,16 @@
4462
4695
  compressionMethod,
4463
4696
  uncompressedSize,
4464
4697
  offset: zipWriter.offset - diskOffset,
4465
- diskNumberStart: diskNumber
4698
+ diskNumberStart: diskNumber,
4699
+ uid,
4700
+ gid,
4701
+ setuid,
4702
+ setgid,
4703
+ sticky,
4704
+ unixMode,
4705
+ msdosAttributesRaw,
4706
+ msdosAttributes,
4707
+ unixExternalUpper
4466
4708
  });
4467
4709
  const headerInfo = getHeaderInfo(options);
4468
4710
  const dataDescriptorInfo = getDataDescriptorInfo(options);
@@ -4654,7 +4896,8 @@
4654
4896
  rawExtraFieldExtendedTimestamp,
4655
4897
  extraFieldExtendedTimestampFlag,
4656
4898
  rawExtraFieldNTFS,
4657
- rawExtraFieldAES
4899
+ rawExtraFieldUnix,
4900
+ rawExtraFieldAES,
4658
4901
  } = headerInfo;
4659
4902
  const { dataDescriptorArray } = dataDescriptorInfo;
4660
4903
  const {
@@ -4686,6 +4929,15 @@
4686
4929
  msDosCompatible,
4687
4930
  internalFileAttributes,
4688
4931
  externalFileAttributes,
4932
+ uid,
4933
+ gid,
4934
+ unixMode,
4935
+ setuid,
4936
+ setgid,
4937
+ sticky,
4938
+ unixExternalUpper,
4939
+ msdosAttributesRaw,
4940
+ msdosAttributes,
4689
4941
  useCompressionStream,
4690
4942
  passThrough
4691
4943
  } = options;
@@ -4703,13 +4955,23 @@
4703
4955
  localExtraFieldZip64Length,
4704
4956
  rawExtraFieldExtendedTimestamp,
4705
4957
  rawExtraFieldNTFS,
4958
+ rawExtraFieldUnix,
4706
4959
  rawExtraFieldAES,
4707
4960
  rawExtraField,
4708
4961
  extendedTimestamp,
4709
4962
  msDosCompatible,
4710
4963
  internalFileAttributes,
4711
4964
  externalFileAttributes,
4712
- diskNumberStart
4965
+ diskNumberStart,
4966
+ uid,
4967
+ gid,
4968
+ unixMode,
4969
+ setuid,
4970
+ setgid,
4971
+ sticky,
4972
+ unixExternalUpper,
4973
+ msdosAttributesRaw,
4974
+ msdosAttributes
4713
4975
  };
4714
4976
  let {
4715
4977
  signature,
@@ -4732,7 +4994,7 @@
4732
4994
  password,
4733
4995
  encryptionStrength,
4734
4996
  zipCrypto: encrypted && zipCrypto,
4735
- passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & 0xFF,
4997
+ passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
4736
4998
  signed: !passThrough,
4737
4999
  compressed: compressed && !passThrough,
4738
5000
  encrypted: encrypted && !passThrough,
@@ -4911,6 +5173,49 @@
4911
5173
  } else {
4912
5174
  rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
4913
5175
  }
5176
+ let rawExtraFieldUnix;
5177
+ try {
5178
+ const { uid, gid, unixMode, setuid, setgid, sticky, unixExtraFieldType } = options;
5179
+ if (unixExtraFieldType && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE || unixMode !== UNDEFINED_VALUE)) {
5180
+ const uidBytes = packUnixId(uid);
5181
+ const gidBytes = packUnixId(gid);
5182
+ let modeArray = new Uint8Array();
5183
+ if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && unixMode !== UNDEFINED_VALUE) {
5184
+ let modeToWrite = unixMode & MAX_16_BITS;
5185
+ if (setuid) {
5186
+ modeToWrite |= FILE_ATTR_UNIX_SETUID_MASK;
5187
+ }
5188
+ if (setgid) {
5189
+ modeToWrite |= FILE_ATTR_UNIX_SETGID_MASK;
5190
+ }
5191
+ if (sticky) {
5192
+ modeToWrite |= FILE_ATTR_UNIX_STICKY_MASK;
5193
+ }
5194
+ modeArray = new Uint8Array(2);
5195
+ const modeDataView = new DataView(modeArray.buffer);
5196
+ modeDataView.setUint16(0, modeToWrite, true);
5197
+ }
5198
+ const payloadLength = 3 + uidBytes.length + gidBytes.length + modeArray.length;
5199
+ rawExtraFieldUnix = new Uint8Array(4 + payloadLength);
5200
+ const rawExtraFieldUnixView = getDataView(rawExtraFieldUnix);
5201
+ setUint16(rawExtraFieldUnixView, 0, unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE ? EXTRAFIELD_TYPE_INFOZIP : EXTRAFIELD_TYPE_UNIX);
5202
+ setUint16(rawExtraFieldUnixView, 2, payloadLength);
5203
+ setUint8(rawExtraFieldUnixView, 4, 1);
5204
+ setUint8(rawExtraFieldUnixView, 5, uidBytes.length);
5205
+ let offset = 6;
5206
+ arraySet(rawExtraFieldUnix, uidBytes, offset);
5207
+ offset += uidBytes.length;
5208
+ setUint8(rawExtraFieldUnixView, offset, gidBytes.length);
5209
+ offset++;
5210
+ arraySet(rawExtraFieldUnix, gidBytes, offset);
5211
+ offset += gidBytes.length;
5212
+ arraySet(rawExtraFieldUnix, modeArray, offset);
5213
+ } else {
5214
+ rawExtraFieldUnix = new Uint8Array();
5215
+ }
5216
+ } catch {
5217
+ rawExtraFieldUnix = new Uint8Array();
5218
+ }
4914
5219
  if (compressionMethod === UNDEFINED_VALUE) {
4915
5220
  compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
4916
5221
  }
@@ -4923,7 +5228,7 @@
4923
5228
  compressionMethod = COMPRESSION_METHOD_AES;
4924
5229
  }
4925
5230
  const localExtraFieldZip64Length = zip64ExtraFieldComplete ? getLength(rawExtraFieldZip64) : 0;
4926
- const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
5231
+ const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
4927
5232
  const {
4928
5233
  headerArray,
4929
5234
  headerView,
@@ -4956,6 +5261,8 @@
4956
5261
  localHeaderOffset += getLength(rawExtraFieldExtendedTimestamp);
4957
5262
  arraySet(localHeaderArray, rawExtraFieldNTFS, localHeaderOffset);
4958
5263
  localHeaderOffset += getLength(rawExtraFieldNTFS);
5264
+ arraySet(localHeaderArray, rawExtraFieldUnix, localHeaderOffset);
5265
+ localHeaderOffset += getLength(rawExtraFieldUnix);
4959
5266
  arraySet(localHeaderArray, rawExtraField, localHeaderOffset);
4960
5267
  if (dataDescriptor) {
4961
5268
  setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + 4, 0);
@@ -4977,6 +5284,7 @@
4977
5284
  localExtraFieldZip64Length,
4978
5285
  rawExtraFieldExtendedTimestamp,
4979
5286
  rawExtraFieldNTFS,
5287
+ rawExtraFieldUnix,
4980
5288
  rawExtraFieldAES,
4981
5289
  extraFieldLength
4982
5290
  };
@@ -5003,6 +5311,46 @@
5003
5311
  entryInfo.metadataSize += extraBytesLength;
5004
5312
  }
5005
5313
 
5314
+ function packUnixId(id) {
5315
+ if (id === UNDEFINED_VALUE) {
5316
+ return new Uint8Array();
5317
+ } else {
5318
+ const dataArray = new Uint8Array(4);
5319
+ const dataView = getDataView(dataArray);
5320
+ dataView.setUint32(0, id, true);
5321
+ let length = 4;
5322
+ while (length > 1 && dataArray[length - 1] === 0) {
5323
+ length--;
5324
+ }
5325
+ return dataArray.subarray(0, length);
5326
+ }
5327
+ }
5328
+
5329
+ function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
5330
+ if (msdosAttributesRaw !== UNDEFINED_VALUE) {
5331
+ msdosAttributesRaw = msdosAttributesRaw & MAX_8_BITS;
5332
+ } else if (msdosAttributes !== UNDEFINED_VALUE) {
5333
+ const { readOnly, hidden, system, directory: msdDir, archive } = msdosAttributes;
5334
+ let raw = 0;
5335
+ if (readOnly) raw |= FILE_ATTR_MSDOS_READONLY_MASK;
5336
+ if (hidden) raw |= FILE_ATTR_MSDOS_HIDDEN_MASK;
5337
+ if (system) raw |= FILE_ATTR_MSDOS_SYSTEM_MASK;
5338
+ if (msdDir) raw |= FILE_ATTR_MSDOS_DIR_MASK;
5339
+ if (archive) raw |= FILE_ATTR_MSDOS_ARCHIVE_MASK;
5340
+ msdosAttributesRaw = raw & MAX_8_BITS;
5341
+ }
5342
+ if (msdosAttributes === UNDEFINED_VALUE) {
5343
+ msdosAttributes = {
5344
+ readOnly: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_READONLY_MASK),
5345
+ hidden: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_HIDDEN_MASK),
5346
+ system: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_SYSTEM_MASK),
5347
+ directory: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_DIR_MASK),
5348
+ archive: Boolean(msdosAttributesRaw & FILE_ATTR_MSDOS_ARCHIVE_MASK)
5349
+ };
5350
+ }
5351
+ return { msdosAttributesRaw, msdosAttributes };
5352
+ }
5353
+
5006
5354
  function getDataDescriptorInfo({
5007
5355
  zip64,
5008
5356
  dataDescriptor,
@@ -5160,6 +5508,7 @@
5160
5508
  rawExtraFieldAES,
5161
5509
  rawComment,
5162
5510
  rawExtraFieldNTFS,
5511
+ rawExtraFieldUnix,
5163
5512
  rawExtraField,
5164
5513
  extendedTimestamp,
5165
5514
  extraFieldExtendedTimestampFlag,
@@ -5184,6 +5533,7 @@
5184
5533
  rawExtraFieldZip64,
5185
5534
  rawExtraFieldAES,
5186
5535
  rawExtraFieldNTFS,
5536
+ rawExtraFieldUnix,
5187
5537
  rawExtraFieldTimestamp,
5188
5538
  rawExtraField);
5189
5539
  }
@@ -5199,6 +5549,7 @@
5199
5549
  rawExtraFieldAES,
5200
5550
  rawExtraFieldExtendedTimestamp,
5201
5551
  rawExtraFieldNTFS,
5552
+ rawExtraFieldUnix,
5202
5553
  rawExtraField,
5203
5554
  rawComment,
5204
5555
  versionMadeBy,
@@ -5215,7 +5566,7 @@
5215
5566
  uncompressedSize,
5216
5567
  compressedSize
5217
5568
  } = fileEntry;
5218
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
5569
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
5219
5570
  setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
5220
5571
  setUint16(directoryView, offset + 4, versionMadeBy);
5221
5572
  if (!zip64UncompressedSize) {
@@ -5250,9 +5601,12 @@
5250
5601
  directoryOffset += getLength(rawExtraFieldExtendedTimestamp);
5251
5602
  arraySet(directoryArray, rawExtraFieldNTFS, directoryOffset);
5252
5603
  directoryOffset += getLength(rawExtraFieldNTFS);
5604
+ arraySet(directoryArray, rawExtraFieldUnix, directoryOffset);
5605
+ directoryOffset += getLength(rawExtraFieldUnix);
5253
5606
  arraySet(directoryArray, rawExtraField, directoryOffset);
5254
5607
  directoryOffset += getLength(rawExtraField);
5255
5608
  arraySet(directoryArray, rawComment, directoryOffset);
5609
+ directoryOffset += getLength(rawComment);
5256
5610
  if (offset - directoryDiskOffset > writer.availableSize) {
5257
5611
  writer.availableSize = 0;
5258
5612
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));