diff --git a/lib/archivers/zip/zip-archive-output-stream.js b/lib/archivers/zip/zip-archive-output-stream.js index 0b17dd49..4a672005 100644 --- a/lib/archivers/zip/zip-archive-output-stream.js +++ b/lib/archivers/zip/zip-archive-output-stream.js @@ -9,6 +9,7 @@ var inherits = require('util').inherits; var crc32 = require('buffer-crc32'); var {CRC32Stream} = require('crc32-stream'); var {DeflateCRC32Stream} = require('crc32-stream'); +var { once } = require('events'); var ArchiveOutputStream = require('../archive-output-stream'); var ZipArchiveEntry = require('./zip-archive-entry'); @@ -120,12 +121,12 @@ ZipArchiveOutputStream.prototype._defaults = function(o) { return o; }; -ZipArchiveOutputStream.prototype._finish = function() { +ZipArchiveOutputStream.prototype._finish = async function() { this._archive.centralOffset = this.offset; - this._entries.forEach(function(ae) { - this._writeCentralFileHeader(ae); - }.bind(this)); + for (const ae of this._entries) { + await this._writeCentralFileHeader(ae); + } this._archive.centralLength = this.offset - this._archive.centralOffset; @@ -260,7 +261,7 @@ ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function() { this.write(zipUtil.getLongBytes(1)); }; -ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) { +ZipArchiveOutputStream.prototype._writeCentralFileHeader = async function(ae) { var gpb = ae.getGeneralPurposeBit(); var method = ae.getMethod(); var offsets = ae._offsets; @@ -268,6 +269,8 @@ ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) { var size = ae.getSize(); var compressedSize = ae.getCompressedSize(); + var continueWriting = true; + if (ae.isZip64() || offsets.file > constants.ZIP64_MAGIC) { size = constants.ZIP64_MAGIC; compressedSize = constants.ZIP64_MAGIC; @@ -286,27 +289,27 @@ ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) { } // signature - this.write(zipUtil.getLongBytes(constants.SIG_CFH)); + if (this.write(zipUtil.getLongBytes(constants.SIG_CFH)) === false) continueWriting = false; // version made by - this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY)); + if (this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY)) === false) continueWriting = false; // version to extract and general bit flag - this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract())); - this.write(gpb.encode()); + if (this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract())) === false) continueWriting = false; + if (this.write(gpb.encode()) === false) continueWriting = false; // compression method - this.write(zipUtil.getShortBytes(method)); + if (this.write(zipUtil.getShortBytes(method)) === false) continueWriting = false; // datetime - this.write(zipUtil.getLongBytes(ae.getTimeDos())); + if (this.write(zipUtil.getLongBytes(ae.getTimeDos())) === false) continueWriting = false; // crc32 checksum - this.write(zipUtil.getLongBytes(ae.getCrc())); + if (this.write(zipUtil.getLongBytes(ae.getCrc())) === false) continueWriting = false; // sizes - this.write(zipUtil.getLongBytes(compressedSize)); - this.write(zipUtil.getLongBytes(size)); + if (this.write(zipUtil.getLongBytes(compressedSize)) === false) continueWriting = false; + if (this.write(zipUtil.getLongBytes(size)) === false) continueWriting = false; var name = ae.getName(); var comment = ae.getComment(); @@ -318,38 +321,42 @@ ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) { } // name length - this.write(zipUtil.getShortBytes(name.length)); + if (this.write(zipUtil.getShortBytes(name.length)) === false) continueWriting = false; // extra length - this.write(zipUtil.getShortBytes(extra.length)); + if (this.write(zipUtil.getShortBytes(extra.length)) === false) continueWriting = false; // comments length - this.write(zipUtil.getShortBytes(comment.length)); + if (this.write(zipUtil.getShortBytes(comment.length)) === false) continueWriting = false;; // disk number start - this.write(constants.SHORT_ZERO); + if (this.write(constants.SHORT_ZERO) === false) continueWriting = false;; // internal attributes - this.write(zipUtil.getShortBytes(ae.getInternalAttributes())); + if (this.write(zipUtil.getShortBytes(ae.getInternalAttributes())) === false) continueWriting = false; // external attributes - this.write(zipUtil.getLongBytes(ae.getExternalAttributes())); + if (this.write(zipUtil.getLongBytes(ae.getExternalAttributes())) === false) continueWriting = false; // relative offset of LFH if (offsets.file > constants.ZIP64_MAGIC) { - this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC)); + if (this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC)) === false) continueWriting = false; } else { - this.write(zipUtil.getLongBytes(offsets.file)); + if (this.write(zipUtil.getLongBytes(offsets.file)) === false) continueWriting = false; } // name - this.write(name); + if (this.write(name) === false) continueWriting = false; // extra - this.write(extra); + if (this.write(extra) === false) continueWriting = false; // comment - this.write(comment); + if (this.write(comment) === false) continueWriting = false; + + if (continueWriting === false) { + await once(this, "drain"); + } }; ZipArchiveOutputStream.prototype._writeDataDescriptor = function(ae) {