zip-stream
Advanced tools
Sorry, the diff of this file is not supported yet
+5
-0
@@ -0,1 +1,6 @@ | ||
| v0.2.2: | ||
| date: 2014-02-25 | ||
| changes: | ||
| - misc bugfixes. | ||
| - initial debug logic. | ||
| v0.2.1: | ||
@@ -2,0 +7,0 @@ date: 2014-02-16 |
+85
-62
@@ -9,3 +9,6 @@ /** | ||
| var inherits = require('util').inherits; | ||
| var util = require('./util'); | ||
| var debug = util.debug('zip-stream:headers'); | ||
| var DEFAULT_FILE_MODE = 0100664; | ||
@@ -17,2 +20,3 @@ var DEFAULT_DIR_MODE = 040755; | ||
| function ZipHeader() { | ||
| this.name = 'zipHeader'; | ||
| this.bufferSize = 0; | ||
@@ -23,30 +27,37 @@ this.fields = []; | ||
| ZipHeader.prototype.toBuffer = function(data) { | ||
| var buf = new Buffer(this.bufferSize); | ||
| var self = this; | ||
| var buf = new Buffer(self.bufferSize); | ||
| var offset = 0; | ||
| var val; | ||
| var valLength; | ||
| var fallback; | ||
| data = this._normalize(data); | ||
| debug('%s:start', self.name); | ||
| this.fields.forEach(function(value) { | ||
| fallback = (value.type === 'string') ? '' : 0; | ||
| val = data[value.field] || value.def || fallback; | ||
| data = self._normalize(data); | ||
| self.fields.forEach(function(field) { | ||
| fallback = (field.type === 'string') ? '' : 0; | ||
| val = data[field.name] || field.def || fallback; | ||
| valLength = (field.lenField && data[field.lenField] > 0) ? data[field.lenField] : field.len; | ||
| var noAssert = false; | ||
| if (value.field === 'externalFileAttributes') { | ||
| if (field.name === 'externalFileAttributes') { | ||
| noAssert = true; | ||
| } | ||
| if (value.lenField) { | ||
| value.len = (data[value.lenField] > 0) ? buf.write(val, offset) : 0; | ||
| } else if (typeof buf['write' + value.type] === 'function') { | ||
| buf['write' + value.type](val, offset, noAssert); | ||
| if (typeof buf['write' + field.type] === 'function') { | ||
| debug('%s:%s:%s:%d+%d', self.name, field.type, field.name, offset, field.len); | ||
| buf['write' + field.type](val, offset, noAssert); | ||
| } else if (val.length > 0) { | ||
| debug('%s:%s:%d+%d', self.name, field.name, offset, val.length); | ||
| buf.write(val, offset); | ||
| } | ||
| offset += value.len; | ||
| offset += valLength; | ||
| }); | ||
| debug('%s:finish:%d', self.name, offset); | ||
| return buf.slice(0, offset); | ||
@@ -56,15 +67,19 @@ }; | ||
| ZipHeader.prototype.toObject = function(buf) { | ||
| var self = this; | ||
| var data = {}; | ||
| var offset = 0; | ||
| var valLength; | ||
| this.fields.forEach(function(value) { | ||
| if (value.lenField) { | ||
| data[value.field] = (data[value.lenField] > 0) ? buf.toString('utf8', offset) : null; | ||
| } else if (typeof buf['read' + value.type] === 'function') { | ||
| data[value.field] = buf['read' + value.type](offset); | ||
| self.fields.forEach(function(field) { | ||
| valLength = (field.lenField && data[field.lenField] > 0) ? data[field.lenField] : field.len; | ||
| if (typeof buf['read' + field.type] === 'function') { | ||
| data[field.name] = buf['read' + field.type](offset); | ||
| } else if (valLength > 0) { | ||
| data[field.name] = buf.toString(null, offset, valLength); | ||
| } else { | ||
| data[value.field] = buf.toString(null, offset, value.len); | ||
| data[field.name] = null; | ||
| } | ||
| offset += value.len; | ||
| offset += valLength; | ||
| }); | ||
@@ -81,2 +96,6 @@ | ||
| data.filenameLength = 0; | ||
| data.commentLength = 0; | ||
| data.extraFieldLength = 0; | ||
| if (data.name) { | ||
@@ -114,16 +133,17 @@ if (Buffer.byteLength(data.name) !== data.name.length) { | ||
| this.name = 'file'; | ||
| this.bufferSize = 1024; | ||
| this.fields = [ | ||
| {field: 'signature', len: 4, type: 'UInt32LE', def: 0x04034b50}, | ||
| {field: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20}, | ||
| {field: 'flags', len: 2, type: 'UInt16LE'}, | ||
| {field: 'compressionMethod', len: 2, type: 'UInt16LE'}, | ||
| {field: 'lastModifiedDate', len: 4, type: 'UInt32LE'}, | ||
| {field: 'crc32', len: 4, type: 'Int32LE', def: 0}, | ||
| {field: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'uncompressedSize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'filenameLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'extraFieldLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'name', len: -1, lenField: 'filenameLength', type: 'string'}, | ||
| {field: 'extraField', len: -1, lenField: 'extraFieldLength', type: 'string'} | ||
| {name: 'signature', len: 4, type: 'UInt32LE', def: 0x04034b50}, | ||
| {name: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20}, | ||
| {name: 'flags', len: 2, type: 'UInt16LE'}, | ||
| {name: 'compressionMethod', len: 2, type: 'UInt16LE'}, | ||
| {name: 'lastModifiedDate', len: 4, type: 'UInt32LE'}, | ||
| {name: 'crc32', len: 4, type: 'Int32LE', def: 0}, | ||
| {name: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'uncompressedSize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'filenameLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'extraFieldLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'name', len: 0, lenField: 'filenameLength', type: 'string'}, | ||
| {name: 'extraField', len: 0, lenField: 'extraFieldLength', type: 'string'} | ||
| ]; | ||
@@ -136,8 +156,9 @@ } | ||
| this.name = 'fileDescriptor'; | ||
| this.bufferSize = 16; | ||
| this.fields = [ | ||
| {field: 'signature', len: 4, type: 'UInt32LE', def: 0x08074b50}, | ||
| {field: 'crc32', len: 4, type: 'Int32LE'}, | ||
| {field: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'uncompressedSize', len: 4, type: 'UInt32LE'} | ||
| {name: 'signature', len: 4, type: 'UInt32LE', def: 0x08074b50}, | ||
| {name: 'crc32', len: 4, type: 'Int32LE'}, | ||
| {name: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'uncompressedSize', len: 4, type: 'UInt32LE'} | ||
| ]; | ||
@@ -150,23 +171,24 @@ } | ||
| this.name = 'centralDirectory'; | ||
| this.bufferSize = 1024; | ||
| this.fields = [ | ||
| {field: 'signature', len: 4, type: 'UInt32LE', def: 0x02014b50}, | ||
| {field: 'versionMadeBy', len: 2, type: 'UInt16LE', def: 20}, | ||
| {field: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20}, | ||
| {field: 'flags', len: 2, type: 'UInt16LE'}, | ||
| {field: 'compressionMethod', len: 2, type: 'UInt16LE'}, | ||
| {field: 'lastModifiedDate', len: 4, type: 'UInt32LE'}, | ||
| {field: 'crc32', len: 4, type: 'Int32LE'}, | ||
| {field: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'uncompressedSize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'filenameLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'extraFieldLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'commentLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'diskNumberStart', len: 2, type: 'UInt16LE'}, | ||
| {field: 'internalFileAttributes', len: 2, type: 'UInt16LE'}, | ||
| {field: 'externalFileAttributes', len: 4, type: 'UInt32LE'}, | ||
| {field: 'offset', len: 4, type: 'UInt32LE'}, | ||
| {field: 'name', len: -1, lenField: 'filenameLength', type: 'string'}, | ||
| {field: 'extraField', len: -1, lenField: 'extraFieldLength', type: 'string'}, | ||
| {field: 'comment', len: -1, lenField: 'commentLength', type: 'string'} | ||
| {name: 'signature', len: 4, type: 'UInt32LE', def: 0x02014b50}, | ||
| {name: 'versionMadeBy', len: 2, type: 'UInt16LE', def: 20}, | ||
| {name: 'versionNeededToExtract', len: 2, type: 'UInt16LE', def: 20}, | ||
| {name: 'flags', len: 2, type: 'UInt16LE'}, | ||
| {name: 'compressionMethod', len: 2, type: 'UInt16LE'}, | ||
| {name: 'lastModifiedDate', len: 4, type: 'UInt32LE'}, | ||
| {name: 'crc32', len: 4, type: 'Int32LE'}, | ||
| {name: 'compressedSize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'uncompressedSize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'filenameLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'extranameLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'commentLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'diskNumberStart', len: 2, type: 'UInt16LE'}, | ||
| {name: 'internalFileAttributes', len: 2, type: 'UInt16LE'}, | ||
| {name: 'externalFileAttributes', len: 4, type: 'UInt32LE'}, | ||
| {name: 'offset', len: 4, type: 'UInt32LE'}, | ||
| {name: 'name', len: 0, lenField: 'filenameLength', type: 'string'}, | ||
| {name: 'extraField', len: 0, lenField: 'extraFieldLength', type: 'string'}, | ||
| {name: 'comment', len: 0, lenField: 'commentLength', type: 'string'} | ||
| ]; | ||
@@ -179,13 +201,14 @@ } | ||
| this.name = 'centralFooter'; | ||
| this.bufferSize = 512; | ||
| this.fields = [ | ||
| {field: 'signature', len: 4, type: 'UInt32LE', def: 0x06054b50}, | ||
| {field: 'diskNumber', len: 2, type: 'UInt16LE'}, | ||
| {field: 'diskNumberStart', len: 2, type: 'UInt16LE'}, | ||
| {field: 'directoryRecordsDisk', len: 2, type: 'UInt16LE'}, | ||
| {field: 'directoryRecords', len: 2, type: 'UInt16LE'}, | ||
| {field: 'centralDirectorySize', len: 4, type: 'UInt32LE'}, | ||
| {field: 'centralDirectoryOffset', len: 4, type: 'UInt32LE'}, | ||
| {field: 'commentLength', len: 2, type: 'UInt16LE'}, | ||
| {field: 'comment', len: -1, lenField: 'commentLength', type: 'string'} | ||
| {name: 'signature', len: 4, type: 'UInt32LE', def: 0x06054b50}, | ||
| {name: 'diskNumber', len: 2, type: 'UInt16LE'}, | ||
| {name: 'diskNumberStart', len: 2, type: 'UInt16LE'}, | ||
| {name: 'directoryRecordsDisk', len: 2, type: 'UInt16LE'}, | ||
| {name: 'directoryRecords', len: 2, type: 'UInt16LE'}, | ||
| {name: 'centralDirectorySize', len: 4, type: 'UInt32LE'}, | ||
| {name: 'centralDirectoryOffset', len: 4, type: 'UInt32LE'}, | ||
| {name: 'commentLength', len: 2, type: 'UInt16LE'}, | ||
| {name: 'comment', len: 0, lenField: 'commentLength', type: 'string'} | ||
| ]; | ||
@@ -192,0 +215,0 @@ } |
@@ -22,5 +22,10 @@ /** | ||
| this.on('data', function(chunk) { | ||
| this.compressedSize += chunk.length; | ||
| }); | ||
| // BC v0.8 | ||
| if (typeof zlib.DeflateRaw.prototype.push !== 'function') { | ||
| this.on('data', function(chunk) { | ||
| if (chunk) { | ||
| this.compressedSize += chunk.length; | ||
| } | ||
| }); | ||
| } | ||
@@ -34,2 +39,10 @@ this.once('end', function() { | ||
| DeflateRawChecksum.prototype.push = function(chunk, encoding) { | ||
| if (chunk) { | ||
| this.compressedSize += chunk.length; | ||
| } | ||
| return zlib.DeflateRaw.prototype.push.call(this, chunk, encoding); | ||
| }; | ||
| DeflateRawChecksum.prototype.write = function(chunk, cb) { | ||
@@ -36,0 +49,0 @@ if (chunk) { |
@@ -16,2 +16,3 @@ /** | ||
| util.debug = require('debug'); | ||
| util.crc32 = require('./crc32'); | ||
@@ -18,0 +19,0 @@ |
+18
-1
@@ -17,8 +17,14 @@ /** | ||
| var debug = util.debug('zip-stream:instance'); | ||
| var debugEntry = util.debug('zip-stream:entry'); | ||
| var ZipStream = module.exports = function(options) { | ||
| if (!(this instanceof ZipStream)) { | ||
| return new ZipStream(opts); | ||
| return new ZipStream(options); | ||
| } | ||
| debug('init'); | ||
| options = this.options = util.defaults(options, { | ||
| highWaterMark: 1024 * 1024, | ||
| comment: '', | ||
@@ -52,2 +58,6 @@ forceUTC: false, | ||
| this._processing = false; | ||
| this.once('end', function() { | ||
| debug('end'); | ||
| }); | ||
| }; | ||
@@ -58,2 +68,4 @@ | ||
| ZipStream.prototype._afterAppend = function(file) { | ||
| debugEntry('%s:finish', file.name); | ||
| this.files.push(file); | ||
@@ -243,2 +255,3 @@ this._processing = false; | ||
| data = this._normalizeFileData(data); | ||
| debugEntry('%s:start', data.name); | ||
@@ -259,4 +272,6 @@ if (data.type !== 'file') { | ||
| if (Buffer.isBuffer(source)) { | ||
| debugEntry('%s:source:buffer', data.name); | ||
| this._appendBuffer(source, data, callback); | ||
| } else if (util.isStream(source)) { | ||
| debugEntry('%s:source:stream', data.name); | ||
| this._appendStream(source, data, callback); | ||
@@ -276,4 +291,6 @@ } else { | ||
| debug('finalize'); | ||
| this._writeCentralDirectory(); | ||
| this._finalized = true; | ||
| debug('finalized'); | ||
| this.end(); | ||
@@ -280,0 +297,0 @@ }; |
+3
-2
| { | ||
| "name": "zip-stream", | ||
| "version": "0.2.1", | ||
| "version": "0.2.2", | ||
| "description": "a streaming zip generator.", | ||
@@ -32,3 +32,4 @@ "homepage": "https://github.com/ctalkington/node-zip-stream", | ||
| "readable-stream": "~1.0.24", | ||
| "lodash.defaults": "~2.4.1" | ||
| "lodash.defaults": "~2.4.1", | ||
| "debug": "~0.7.4" | ||
| }, | ||
@@ -35,0 +36,0 @@ "devDependencies": { |
+18
-1
@@ -1,2 +0,2 @@ | ||
| # zip-stream v0.2.1 [](http://travis-ci.org/ctalkington/node-zip-stream) | ||
| # zip-stream v0.2.2 [](http://travis-ci.org/ctalkington/node-zip-stream) | ||
@@ -91,2 +91,19 @@ zip-stream is a streaming zip generator. It was built to be a successor to [zipstream](https://npmjs.org/package/zipstream). Dependencies are kept to a minimum through the use of many of node's built-in modules including the use of zlib module for compression. | ||
| ## Debugging | ||
| This library makes use of the [debug](https://npmjs.org/package/debug) module with a namespace of `zip-stream` which can be triggered by setting `DEBUG` in your environment like so: | ||
| ```shell | ||
| # unix | ||
| DEBUG=zip-stream:* node script | ||
| # windows (powershell) | ||
| $env:DEBUG="zip-stream:*" | ||
| node script | ||
| # windows (cmd) | ||
| SET DEBUG="zip-stream:*" | ||
| node script | ||
| ``` | ||
| ## Things of Interest | ||
@@ -93,0 +110,0 @@ |
@@ -66,2 +66,8 @@ var crypto = require('crypto'); | ||
| function fileBuffer(filepath) { | ||
| return fs.readFileSync(filepath); | ||
| } | ||
| module.exports.fileBuffer = fileBuffer; | ||
| function WriteHashStream(path, options) { | ||
@@ -68,0 +74,0 @@ fs.WriteStream.call(this, path, options); |
+37
-0
@@ -9,2 +9,3 @@ /*global before,describe,it */ | ||
| var binaryBuffer = helpers.binaryBuffer; | ||
| var fileBuffer = helpers.fileBuffer; | ||
| var WriteHashStream = helpers.WriteHashStream; | ||
@@ -246,4 +247,40 @@ | ||
| it('should support compressing images for Buffer sources', function(done) { | ||
| var archive = new packer({ | ||
| forceUTC: true | ||
| }); | ||
| var testStream = new WriteHashStream('tmp/buffer-image.zip'); | ||
| testStream.on('close', function() { | ||
| assert.equal(testStream.digest, '318b485627b9abf7cbd411e43985fc8d7358d151'); | ||
| done(); | ||
| }); | ||
| archive.pipe(testStream); | ||
| archive.entry(fileBuffer('test/fixtures/image.png'), { name: 'image.png', date: testDate }); | ||
| archive.finalize(); | ||
| }); | ||
| it('should support compressing images for Stream sources', function(done) { | ||
| var archive = new packer({ | ||
| forceUTC: true | ||
| }); | ||
| var testStream = new WriteHashStream('tmp/stream-image.zip'); | ||
| testStream.on('close', function() { | ||
| assert.equal(testStream.digest, '318b485627b9abf7cbd411e43985fc8d7358d151'); | ||
| done(); | ||
| }); | ||
| archive.pipe(testStream); | ||
| archive.entry(fs.createReadStream('test/fixtures/image.png'), { name: 'image.png', date: testDate }); | ||
| archive.finalize(); | ||
| }); | ||
| }); | ||
| }); |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
163661
175.61%29
3.57%1108
7.16%116
17.17%3
50%+ Added
+ Added