Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
ZipCryptoStream.prototype._appendStream = function(ae, source, callback) {
ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
ae.getGeneralPurposeBit().useDataDescriptor(false);
// we will write local file header after we get CRC back
// it seems as if using data descriptor is not supported when encrypting data with ZipCrypto
// so we have to write CRC into local file header
// this._writeLocalFileHeader(ae);
var smart = this._smartStream(ae, callback);
source.once('error', function(err) {
smart.emit('error', err);
smart.end();
});
source.pipe(smart);
};
if (data.type !== 'file' && data.type !== 'directory' && data.type !== 'symlink') {
callback(new Error(data.type + ' entries not currently supported'));
return;
}
if (typeof data.name !== 'string' || data.name.length === 0) {
callback(new Error('entry name must be a non-empty string value'));
return;
}
if (data.type === 'symlink' && typeof data.linkname !== 'string') {
callback(new Error('entry linkname must be a non-empty string value when type equals symlink'));
return;
}
var entry = new ZipArchiveEntry(data.name);
entry.setTime(data.date, this.options.forceLocalTime);
if (data.store) {
entry.setMethod(0);
}
if (data.comment.length > 0) {
entry.setComment(data.comment);
}
if (data.type === 'symlink' && typeof data.mode !== 'number') {
data.mode = 40960; // 0120000
}
if (typeof data.mode === 'number') {
if (data.type === 'symlink') {
if (data.type !== 'file' && data.type !== 'directory' && data.type !== 'symlink') {
callback(new Error(data.type + ' entries not currently supported'));
return;
}
if (typeof data.name !== 'string' || data.name.length === 0) {
callback(new Error('entry name must be a non-empty string value'));
return;
}
if (data.type === 'symlink' && typeof data.linkname !== 'string') {
callback(new Error('entry linkname must be a non-empty string value when type equals symlink'));
return;
}
var entry = new ZipArchiveEntry(data.name);
entry.setTime(data.date, this.options.forceLocalTime);
if (data.store) {
entry.setMethod(0);
}
if (data.comment.length > 0) {
entry.setComment(data.comment);
}
if (data.type === 'symlink' && typeof data.mode !== 'number') {
data.mode = 40960; // 0120000
}
if (typeof data.mode === 'number') {
if (data.type === 'symlink') {
ZipCryptoStream.prototype._smartStream = function (ae, callback) {
let deflate = ae.getMethod() === constants.METHOD_DEFLATED;
let compressionStream = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();
let error = null;
let bufferedData = [];
compressionStream.once('error', function (err) {
error = err;
});
compressionStream.on('data', (data) => {
bufferedData.push(data);
});
compressionStream.once('end', () => {
let crc = compressionStream.digest();
// gather complete information for CRC and sizes
ZipCryptoStream.prototype._appendBuffer = function(ae, source, callback) {
ae.gpb.useEncryption(true);
// Use data descriptor whatever the method is,
// because when using encryption, we need to calculate
// the compressed size with encrypted data.
ae.gpb.useDataDescriptor(true);
ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
if (source.length === 0) {
ae.setMethod(constants.METHOD_STORED);
}
this._writeLocalFileHeader(ae);
var method = ae.getMethod();
if (
method === constants.METHOD_STORED ||
method === constants.METHOD_DEFLATED
) {
this._smartStream(ae, callback).end(source);
} else {
callback(new Error('compression method ' + method + ' not implemented'));
}
data.mode = 40960; // 0120000
}
if (typeof data.mode === 'number') {
if (data.type === 'symlink') {
data.mode |= 40960;
}
entry.setUnixMode(data.mode);
}
if (data.type === 'symlink' && typeof data.linkname === 'string') {
source = Buffer.from(data.linkname);
}
return ZipArchiveOutputStream.prototype.entry.call(this, entry, source, callback);
};
ZipCryptoStream.prototype._appendBuffer = function(ae, source, callback) {
ae.gpb.useEncryption(true);
// Use data descriptor whatever the method is,
// because when using encryption, we need to calculate
// the compressed size with encrypted data.
ae.gpb.useDataDescriptor(true);
ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
if (source.length === 0) {
ae.setMethod(constants.METHOD_STORED);
}
this._writeLocalFileHeader(ae);
var method = ae.getMethod();
if (
method === constants.METHOD_STORED ||
method === constants.METHOD_DEFLATED
) {
this._smartStream(ae, callback).end(source);
} else {
callback(new Error('compression method ' + method + ' not implemented'));
}
};
ZipCryptoStream.prototype._smartStream = function(ae, callback) {
var zipCrypto = new ZipCrypto(this.options);
zipCrypto.init();
var encryptionHeader = Buffer.from(cryptoRandomString(24), 'hex');
var encryptedHeader = zipCrypto.encrypt(encryptionHeader);
var crc = ae.getTimeDos();
encryptedHeader[10] = crc & 0xff;
encryptedHeader[11] = (crc >> 8) & 0xff;
zipCrypto.init();
var encryptedHeader2 = zipCrypto.encrypt(encryptedHeader);
this.write(encryptedHeader2);
var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
var process = deflate
? new DeflateCRC32Stream(this.options.zlib)
: new CRC32Stream();
var error = null;
function handleStuff() {
var digest = process.digest().readUInt32BE(0);
ae.setCrc(digest);
ae.setSize(process.size());
ae.setCompressedSize(process.size(true) + encryptionHeader.length);
this._afterAppend(ae);
callback(error, ae);
}
var outStream = new Writable({
write: function(chunk, encoding, callback) {
var buffer = zipCrypto.encrypt(chunk);
var inherits = require('util').inherits;
var Writable = require('stream').Writable;
var ZipArchiveOutputStream = require('compress-commons').ZipArchiveOutputStream;
var cryptoRandomString = require('crypto-random-string');
var CRC32Stream = require('crc32-stream').CRC32Stream;
var DeflateCRC32Stream = require('crc32-stream').DeflateCRC32Stream;
var constants = require('compress-commons/lib/archivers/zip/constants');
var ZipCrypto = require('./zip-crypto');
var ZipStream = require('zip-stream');
var ZipCryptoStream = (module.exports = function(options) {
if (!(this instanceof ZipCryptoStream)) {
return new ZipCryptoStream(options);
}
options = this.options = options || {};
options.zlib = options.zlib || {};
/**
* ZipStream
*
* @ignore
* @license [MIT]{@link https://github.com/archiverjs/node-zip-stream/blob/master/LICENSE}
* @copyright (c) 2014 Chris Talkington, contributors.
*/
var inherits = require('util').inherits;
var ZipArchiveOutputStream = require('compress-commons').ZipArchiveOutputStream;
var ZipArchiveEntry = require('compress-commons').ZipArchiveEntry;
var util = require('archiver-utils');
/**
* @constructor
* @extends external:ZipArchiveOutputStream
* @param {Object} [options]
* @param {String} [options.comment] Sets the zip archive comment.
* @param {Boolean} [options.forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
* @param {Boolean} [options.forceZip64=false] Forces the archive to contain ZIP64 headers.
* @param {Boolean} [options.store=false] Sets the compression method to STORE.
* @param {Object} [options.zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
* to control compression.
*/
var ZipStream = module.exports = function(options) {