Comparing version 3.2.1 to 3.3.0
48
index.js
@@ -282,2 +282,5 @@ var fs = require("fs"); | ||
centralDirectorySize += CENTRAL_DIRECTORY_RECORD_FIXED_SIZE + entry.utf8FileName.length + entry.fileComment.length; | ||
if (!entry.forceDosTimestamp) { | ||
centralDirectorySize += INFO_ZIP_UNIVERSAL_TIMESTAMP_EXTRA_FIELD_SIZE; | ||
} | ||
if (useZip64Format) { | ||
@@ -431,2 +434,3 @@ centralDirectorySize += ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE; | ||
this.setLastModDate(options.mtime != null ? options.mtime : new Date()); | ||
this.forceDosTimestamp = !!options.forceDosTimestamp; | ||
if (options.mode != null) { | ||
@@ -474,2 +478,3 @@ this.setFileAttributesMode(options.mode); | ||
Entry.prototype.setLastModDate = function(date) { | ||
this.mtime = date; | ||
var dosDateTime = dateToDosDateTime(date); | ||
@@ -581,2 +586,3 @@ this.lastModFileTime = dosDateTime.time; | ||
var CENTRAL_DIRECTORY_RECORD_FIXED_SIZE = 46; | ||
var INFO_ZIP_UNIVERSAL_TIMESTAMP_EXTRA_FIELD_SIZE = 9; | ||
var ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE = 28; | ||
@@ -588,7 +594,31 @@ Entry.prototype.getCentralDirectoryRecord = function() { | ||
var izutefBuffer = EMPTY_BUFFER; | ||
if (!this.forceDosTimestamp) { | ||
// Here is one specification for this: https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.html | ||
// See also the Info-ZIP source code unix/unix.c:set_extra_field() and zipfile.c:ef_scan_ut_time(). | ||
izutefBuffer = bufferAlloc(INFO_ZIP_UNIVERSAL_TIMESTAMP_EXTRA_FIELD_SIZE); | ||
// 0x5455 Short tag for this extra block type ("UT") | ||
izutefBuffer.writeUInt16LE(0x5455, 0); | ||
// TSize Short total data size for this block | ||
izutefBuffer.writeUInt16LE(INFO_ZIP_UNIVERSAL_TIMESTAMP_EXTRA_FIELD_SIZE - 4, 2); | ||
// See Info-ZIP source code zip.h for these constant values: | ||
var EB_UT_FL_MTIME = (1 << 0); | ||
var EB_UT_FL_ATIME = (1 << 1); | ||
// Note that we set the atime flag despite not providing the atime field. | ||
// The central directory version of this extra field is specified to never contain the atime field even when the flag is set. | ||
// We set it to match the Info-ZIP behavior in order to minimize incompatibility with zip file readers that may have rigid input expectations. | ||
// Flags Byte info bits | ||
izutefBuffer.writeUInt8(EB_UT_FL_MTIME | EB_UT_FL_ATIME, 4); | ||
// (ModTime) Long time of last modification (UTC/GMT) | ||
var timestamp = Math.floor(this.mtime.getTime() / 1000); | ||
if (timestamp < -0x80000000) timestamp = -0x80000000; // 1901-12-13T20:45:52.000Z | ||
if (timestamp > 0x7fffffff) timestamp = 0x7fffffff; // 2038-01-19T03:14:07.000Z | ||
izutefBuffer.writeUInt32LE(timestamp, 5); | ||
} | ||
var normalCompressedSize = this.compressedSize; | ||
var normalUncompressedSize = this.uncompressedSize; | ||
var normalRelativeOffsetOfLocalHeader = this.relativeOffsetOfLocalHeader; | ||
var versionNeededToExtract; | ||
var zeiefBuffer; | ||
var versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_UTF8; | ||
var zeiefBuffer = EMPTY_BUFFER; | ||
if (this.useZip64Format()) { | ||
@@ -614,5 +644,2 @@ normalCompressedSize = 0xffffffff; | ||
// (omit) | ||
} else { | ||
versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_UTF8; | ||
zeiefBuffer = EMPTY_BUFFER; | ||
} | ||
@@ -643,3 +670,3 @@ | ||
// extra field length 2 bytes | ||
fixedSizeStuff.writeUInt16LE(zeiefBuffer.length, 30); | ||
fixedSizeStuff.writeUInt16LE(izutefBuffer.length + zeiefBuffer.length, 30); | ||
// file comment length 2 bytes | ||
@@ -661,2 +688,3 @@ fixedSizeStuff.writeUInt16LE(this.fileComment.length, 32); | ||
// extra field (variable size) | ||
izutefBuffer, | ||
zeiefBuffer, | ||
@@ -673,3 +701,11 @@ // file comment (variable size) | ||
// These are intentionally computed in the current system timezone | ||
// to match how the DOS encoding operates in this library. | ||
var minDosDate = new Date(1980, 0, 1); | ||
var maxDosDate = new Date(2107, 11, 31, 23, 59, 58); | ||
function dateToDosDateTime(jsDate) { | ||
// Clamp out of bounds timestamps. | ||
if (jsDate < minDosDate) jsDate = minDosDate; | ||
else if (jsDate > maxDosDate) jsDate = maxDosDate; | ||
var date = 0; | ||
@@ -676,0 +712,0 @@ date |= jsDate.getDate() & 0x1f; // 1-31 |
{ | ||
"name": "yazl", | ||
"version": "3.2.1", | ||
"version": "3.3.0", | ||
"description": "yet another zip library for node", | ||
@@ -29,3 +29,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"yauzl": "^3.1.3" | ||
"yauzl": "^3.2.0" | ||
}, | ||
@@ -32,0 +32,0 @@ "files": [ |
@@ -68,2 +68,3 @@ # yazl | ||
forceZip64Format: false, | ||
forceDosTimestamp: false, | ||
fileComment: "", // or a UTF-8 Buffer | ||
@@ -90,2 +91,10 @@ } | ||
Since yazl version 3.3.0, yazl includes the Info-ZIP "universal timestamp" extended field (`0x5455` aka `"UT"`) to encode the `mtime`. | ||
The Info-ZIP timestamp is a more modern encoding for the mtime and is generally recommended. | ||
Set `forceDosTimestamp` to `true` to revert to the pre-3.3.0 behvior, disabling this extended field. | ||
The DOS encoding is always included regardless of this option, because it is required in the fixed-size metadata of every archive entry. | ||
The benefits of the Info-ZIP encoding include: timezone is specified as always UTC, which is better for cloud environments and any teams working in multiple timezones; capable of encoding "time 0", the unix epoch in 1970, which is better for some package managers; the precision is 1-second accurate rather than rounded to the nearest even second. The disadvantages of including this field are: it requires an extra 9 bytes of metadata per entry added to the archive. | ||
When attempting to encode an `mtime` outside the supported range for either format, such as the year 1970 in the DOS format or the year 2039 for the modern format, the time will clamped to the closest supported time. | ||
If `fileComment` is a `string`, it will be encoded with UTF-8. | ||
@@ -131,2 +140,3 @@ If `fileComment` is a `Buffer`, it should be a UTF-8 encoded string. | ||
forceZip64Format: false, | ||
forceDosTimestamp: false, | ||
fileComment: "", // or a UTF-8 Buffer | ||
@@ -137,3 +147,3 @@ size: 12345, // example value | ||
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `compressionLevel`, `forceZip64Format`, and `fileComment`. | ||
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `compressionLevel`, `forceZip64Format`, `forceDosTimestamp`, and `fileComment`. | ||
If `size` is given, it will be checked against the actual number of bytes in the `readStream`, | ||
@@ -169,2 +179,3 @@ and an error will be emitted if there is a mismatch. | ||
forceZip64Format: false, | ||
forceDosTimestamp: false, | ||
fileComment: "", // or a UTF-8 Buffer | ||
@@ -174,3 +185,3 @@ } | ||
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `compressionLevel`, `forceZip64Format`, and `fileComment`. | ||
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `compressionLevel`, `forceZip64Format`, `forceDosTimestamp`, and `fileComment`. | ||
@@ -219,6 +230,7 @@ This method has the unique property that General Purpose Bit `3` will not be used in the Local File Header. | ||
mode: 040775, | ||
forceDosTimestamp: false, | ||
} | ||
``` | ||
See `addFile()` for the meaning of `mtime` and `mode`. | ||
See `addFile()` for the meaning of `mtime`, `mode`, and `forceDosTimestamp`. | ||
@@ -295,5 +307,10 @@ #### end([options], [calculatedTotalSizeCallback]) | ||
`jsDate` is a `Date` instance. | ||
Returns `{date: date, time: time}`, where `date` and `time` are unsigned 16-bit integers. | ||
*Deprecated* since yazl 3.3.0. | ||
This function only remains exported in order to maintain compatibility with older versions of yazl. | ||
It will be removed in yazl 4.0.0 unless someone asks for it to remain supported. | ||
If you ever have a use case for calling this function directly please | ||
[open an issue against yazl](https://github.com/thejoshwolfe/yazl/issues/new) | ||
requesting that this function be properly supported again. | ||
## Regarding ZIP64 Support | ||
@@ -395,2 +412,7 @@ | ||
* 3.3.0 (2024-Nov-08) | ||
* Add support for encoding timestamps in the more modern Info-ZIP "universal timestamp" extended field (`0x5455` aka `"UT"`): supports years as old as 1901 instead of only 1980, notably including 1970; encodes timestamp in UTC rather than an unspecified system-dependent local timezone. | ||
* Disable spending the extra 9 bytes of metadata per entry with `forceDosTimestamp:true`. | ||
* Out-of-bounds timestamps are now clamped rather than overflowing/underflowing and wrapping around. | ||
* Marked `dateToDosDateTime()` as deprecated. | ||
* 3.2.1 (2024-Nov-03) | ||
@@ -397,0 +419,0 @@ * Fix typo in `addBuffer()` where `compressionLevel` wasn't being passed to zlib. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58451
772
456