Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ After UTF-8 encoding, `metadataPath` must be at most `0xffff` bytes in length.
mode: stats.mode,
compress: true,
forceZip64Format: false,
extraFields: [],
fileComment: "", // or a UTF-8 Buffer
}
```
Expand All @@ -85,6 +86,8 @@ If `forceZip64Format` is `true`, yazl will use ZIP64 format in this entry's Data
and Central Directory Record regardless of if it's required or not (this may be useful for testing.).
Otherwise, yazl will use ZIP64 format where necessary.

Each entry in `extraFields` should be tagged data of the form `{id: id, data: data}`. See the [`yauzl` docs](https://github.com/thejoshwolfe/yauzl#extrafields) for more.

If `fileComment` is a `string`, it will be encoded with UTF-8.
If `fileComment` is a `Buffer`, it should be a UTF-8 encoded string.
In UTF-8, `fileComment` must be at most `0xffff` bytes in length.
Expand All @@ -107,12 +110,13 @@ See `addFile()` for info about the `metadataPath` parameter.
mode: 0o100664,
compress: true,
forceZip64Format: false,
extraFields: [],
fileComment: "", // or a UTF-8 Buffer
size: 12345, // example value
}
```

See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `forceZip64Format`, and `fileComment`.
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `forceZip64Format`, `extraFields`, and `fileComment`.
If `size` is given, it will be checked against the actual number of bytes in the `readStream`,
and an error will be emitted if there is a mismatch.

Expand All @@ -132,11 +136,12 @@ See `addFile()` for info about the `metadataPath` parameter.
mode: 0o100664,
compress: true,
forceZip64Format: false,
extraFields: [],
fileComment: "", // or a UTF-8 Buffer
}
```

See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `forceZip64Format`, and `fileComment`.
See `addFile()` for the meaning of `mtime`, `mode`, `compress`, `forceZip64Format`, `extraFields`, and `fileComment`.

This method has the unique property that General Purpose Bit `3` will not be used in the Local File Header.
This doesn't matter for unzip implementations that conform to the Zip File Spec.
Expand Down
20 changes: 18 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,9 @@ function Entry(metadataPath, isDirectory, options) {
// no comment.
this.fileComment = EMPTY_BUFFER;
}
if (options.extraFields) {
this.extraFields = options.extraFields;
}
}
Entry.WAITING_FOR_METADATA = 0;
Entry.READY_TO_PUMP_FILE_DATA = 1;
Expand Down Expand Up @@ -570,6 +573,17 @@ Entry.prototype.getCentralDirectoryRecord = function() {
zeiefBuffer = EMPTY_BUFFER;
}

// Serialize any extra tagged fields.
var extraFieldsBuffer = bufferAlloc(0);
if (this.extraFields) {
this.extraFields.forEach(function(extraField) {
var tagBuffer = bufferAlloc(4);
tagBuffer.writeUInt16LE(extraField.id, 0);
tagBuffer.writeUInt16LE(extraField.data.length, 2);
extraFieldsBuffer = Buffer.concat([extraFieldsBuffer, tagBuffer, extraField.data]);
});
}

// central file header signature 4 bytes (0x02014b50)
fixedSizeStuff.writeUInt32LE(0x02014b50, 0);
// version made by 2 bytes
Expand All @@ -593,7 +607,7 @@ Entry.prototype.getCentralDirectoryRecord = function() {
// file name length 2 bytes
fixedSizeStuff.writeUInt16LE(this.utf8FileName.length, 28);
// extra field length 2 bytes
fixedSizeStuff.writeUInt16LE(zeiefBuffer.length, 30);
fixedSizeStuff.writeUInt16LE(zeiefBuffer.length + extraFieldsBuffer.length, 30);
// file comment length 2 bytes
fixedSizeStuff.writeUInt16LE(this.fileComment.length, 32);
// disk number start 2 bytes
Expand All @@ -609,8 +623,10 @@ Entry.prototype.getCentralDirectoryRecord = function() {
fixedSizeStuff,
// file name (variable size)
this.utf8FileName,
// extra field (variable size)
// zip64 extra field (variable size)
zeiefBuffer,
// other extra fields (variable size)
extraFieldsBuffer,
// file comment (variable size)
this.fileComment,
]);
Expand Down
12 changes: 8 additions & 4 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ var yauzl = require("yauzl");
var BufferList = require("bl");

(function() {
var fileMetadata = {
var options = {
mtime: new Date(),
mode: 0100664,
extraFields: [{
id: 0x7875,
data: new Buffer([1,4,232,3,0,0,4,232,3,0,0]),
}]
};
var zipfile = new yazl.ZipFile();
zipfile.addFile(__filename, "unicōde.txt");
zipfile.addFile(__filename, "without-compression.txt", {compress: false});
zipfile.addReadStream(fs.createReadStream(__filename), "readStream.txt", fileMetadata);
zipfile.addReadStream(fs.createReadStream(__filename), "readStream.txt", options);
var expectedContents = fs.readFileSync(__filename);
zipfile.addBuffer(expectedContents, "with/directories.txt", fileMetadata);
zipfile.addBuffer(expectedContents, "with\\windows-paths.txt", fileMetadata);
zipfile.addBuffer(expectedContents, "with/directories.txt", options);
zipfile.addBuffer(expectedContents, "with\\windows-paths.txt", options);
zipfile.end(function(finalSize) {
if (finalSize !== -1) throw new Error("finalSize is impossible to know before compression");
zipfile.outputStream.pipe(new BufferList(function(err, data) {
Expand Down