Socket
Socket
Sign inDemoInstall

archiver

Package Overview
Dependencies
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

archiver - npm Package Compare versions

Comparing version 0.4.5 to 0.4.6

test/fixtures/headers/tar-fileprefix.bin

27

lib/archiver/core.js

@@ -96,2 +96,14 @@ /**

Archiver.prototype._normalizeFileData = function(data) {
data = util.defaults(data, {
name: null,
date: null
});
data.name = util.sanitizeFilePath(data.name);
data.date = util.dateify(data.date);
return data;
};
Archiver.prototype.append = function(source, data, callback) {

@@ -101,2 +113,13 @@ var sourceCompatMode = false;

data = this._normalizeFileData(data);
if (typeof callback !== 'function') {
callback = this._emitErrorCallback.bind(this);
}
if (typeof data.name !== 'string' || data.name.length === 0) {
callback(new Error('File name is empty or not a valid string value'));
return this;
}
if (typeof source === 'string') {

@@ -114,6 +137,2 @@ source = new Buffer(source, 'utf-8');

if (typeof callback !== 'function') {
callback = this._emitErrorCallback.bind(this);
}
if (this.archiver.processing || this.archiver.queue.length) {

@@ -120,0 +139,0 @@ this.archiver.queue.push({

50

lib/archiver/tar.js

@@ -37,2 +37,15 @@ /**

ArchiverTar.prototype._normalizeFileData = function(data) {
data = util.defaults(data, {
name: null,
date: null
});
data.name = util.sanitizeFilePath(data.name);
data.date = util.dateify(data.date);
data.size = 0;
return data;
};
ArchiverTar.prototype._processFile = function(source, data, callback) {

@@ -42,40 +55,11 @@ var self = this;

var file = util.defaults(data, {
name: null,
comment: '',
date: null,
gid: 0,
mode: null,
mtime: null,
uid: 0
});
var file = self.archiver.file = data;
if (typeof file.name !== 'string' || file.name.length === 0) {
callback(new Error('File name is empty or not a valid string value'));
if (file.name.length > 255) {
callback(new Error('Filename "' + file.name + '" is too long even with prefix support [' + file.name.length + '/255]'));
return;
}
file.name = util.sanitizeFilePath(file.name);
file.type = '0';
file.size = 0;
file.date = util.dateify(file.date);
if (typeof file.mtime !== 'number') {
file.mtime = util.octalDateTime(file.date);
}
file.gid = typeof file.gid === 'number' ? file.gid : 0;
file.mode = typeof file.mode === 'number' ? file.mode : parseInt('777', 8) & 0xfff;
file.uid = typeof file.uid === 'number' ? file.uid : 0;
file.mode = util.padNumber(file.mode, 7);
file.uid = util.padNumber(file.uid, 7);
file.gid = util.padNumber(file.gid, 7);
file.mtime = util.padNumber(file.mtime, 11);
file.offset = self.archiver.pointer;
self.archiver.file = file;
var sourceBuffer;

@@ -85,3 +69,3 @@ var extraBytes;

function onend() {
file.size = util.padNumber(sourceBuffer.length, 11);
file.size = sourceBuffer.length;
extraBytes = self.recordSize - (sourceBuffer.length % self.recordSize || self.recordSize);

@@ -88,0 +72,0 @@

@@ -57,3 +57,3 @@ /**

centralDirectoryBuffer = headers.encode('centralHeader', file);
centralDirectoryBuffer = headers.encode('centralDirectory', file);
centralDirectoryBuffers.push(centralDirectoryBuffer);

@@ -68,4 +68,4 @@ ptr += centralDirectoryBuffer.length;

directoryRecords: files.length,
directorySize: cdsize,
directoryOffset: cdoffset,
centralDirectorySize: cdsize,
centralDirectoryOffset: cdoffset,
comment: comment

@@ -82,39 +82,34 @@ };

ArchiverZip.prototype._processFile = function(source, data, callback) {
var self = this;
self.archiver.processing = true;
var file = util.defaults(data, {
ArchiverZip.prototype._normalizeFileData = function(data) {
data = util.defaults(data, {
name: null,
comment: '',
date: null,
mode: null,
store: false,
lastModifiedDate: null
comment: ''
});
if (this.options.zlib && this.options.zlib.level === 0) {
file.store = true;
data.name = util.sanitizeFilePath(data.name);
data.date = util.dateify(data.date);
if (typeof data.lastModifiedDate !== 'number') {
data.lastModifiedDate = util.dosDateTime(data.date, this.options.forceUTC);
}
if (typeof file.name !== 'string' || file.name.length === 0) {
callback(new Error('File name is empty or not a valid string value'));
return;
if (this.options.zlib && this.options.zlib.level === 0) {
data.store = true;
}
file.name = util.sanitizeFilePath(file.name);
file.date = util.dateify(file.date);
data.flags = (1<<3) | (1<<11);
data.compressionMethod = data.store ? 0 : 8;
data.uncompressedSize = 0;
data.compressedSize = 0;
if (typeof file.lastModifiedDate !== 'number') {
file.lastModifiedDate = util.dosDateTime(file.date, self.options.forceUTC);
}
return data;
};
file.versionMadeBy = 20;
file.versionNeededToExtract = 20;
file.flags = (1<<3) | (1<<11);
file.compressionMethod = file.store ? 0 : 8;
file.uncompressedSize = 0;
file.compressedSize = 0;
ArchiverZip.prototype._processFile = function(source, data, callback) {
var self = this;
self.archiver.processing = true;
self.archiver.file = file;
var file = self.archiver.file = data;

@@ -121,0 +116,0 @@ file.offset = self.archiver.pointer;

@@ -8,99 +8,216 @@ /**

*/
var path = require('path');
var inherits = require('util').inherits;
var util = require('../util');
var headers = {};
function HeaderTar() {
this.bufferSize = 0;
this.fields = [];
}
headers.file = {
fields: [
{'field': 'name', 'length': 100, 'type': 'string'},
{'field': 'mode', 'length': 8, 'type': 'number'},
{'field': 'uid', 'length': 8, 'type': 'number'},
{'field': 'gid', 'length': 8, 'type': 'number'},
{'field': 'size','length': 12, 'type': 'number'},
{'field': 'mtime', 'length': 12, 'type': 'number'},
{'field': 'checksum', 'length': 8, 'type': 'string', 'default': util.repeat(' ', 8)},
{'field': 'type', 'length': 1, 'type': 'number'},
{'field': 'linkName', 'length': 100, 'type': 'string'},
{'field': 'ustar', 'length': 8, 'type': 'string', 'default': 'ustar '},
{'field': 'owner', 'length': 32, 'type': 'string'},
{'field': 'group', 'length': 32, 'type': 'string'},
{'field': 'majorNumber', 'length': 8, 'type': 'number'},
{'field': 'minorNumber', 'length': 8, 'type': 'number'},
{'field': 'filenamePrefix', 'length': 155, 'type': 'string'},
{'field': 'padding', 'length': 12}
],
function HeaderTarFile() {
HeaderTar.call(this);
toBuffer: function(data) {
var self = this;
this.bufferSize = 512;
this.fields = [
{field: 'name', len: 100, type: 'string'},
{field: 'mode', len: 8, type: 'number'},
{field: 'uid', len: 8, type: 'number'},
{field: 'gid', len: 8, type: 'number'},
{field: 'size',len: 12, type: 'number'},
{field: 'mtime', len: 12, type: 'number'},
{field: 'checksum', len: 8, type: 'number'},
{field: 'type', len: 1, type: 'string', def: '0'},
{field: 'linkName', len: 100, type: 'string'},
{field: 'ustar', len: 6, type: 'string', def: 'ustar'},
{field: 'ustarVersion', len: 2, type: 'string', def: '00'},
{field: 'owner', len: 32, type: 'string', def: 'root'},
{field: 'group', len: 32, type: 'string', def: 'root'},
{field: 'devMajor', len: 8, type: 'number'},
{field: 'devMinor', len: 8, type: 'number'},
{field: 'prefix', len: 155, type: 'string'},
{field: 'padding', len: 12, type: 'padding'}
];
}
inherits(HeaderTarFile, HeaderTar);
var buffer = util.cleanBuffer(512);
var offset = 0;
HeaderTarFile.prototype.toBuffer = function(data) {
var self = this;
var buf = util.cleanBuffer(self.bufferSize);
var offset = 0;
var val;
var val;
var fallback;
self.fields.forEach(function(value) {
val = data[value.field] || value.default || '';
data = self._normalize(data);
buffer.write(val, offset);
offset += value.length;
});
self.fields.forEach(function(value) {
fallback = (value.type === 'number') ? 0 : '';
val = data[value.field] || value.def || fallback;
var checksum = self.createChecksum(buffer);
for (var i = 0, length = 6; i < length; i += 1) {
buffer[i + 148] = checksum.charCodeAt(i);
if (value.field === 'checksum') {
val = util.repeat(' ', 8);
} else if (value.type === 'number') {
val = self._prepNumeric(val, value.len);
} else if (value.type === 'string') {
if (typeof val === 'number') {
val = val.toString();
}
}
buffer[154] = 0;
buffer[155] = 0x20;
buf.write(val, offset);
return buffer;
},
offset += value.len;
});
toObject: function(buffer) {
var self = this;
var checksum = this._createChecksum(buf);
var data = {};
var offset = 0;
for (var i = 0, length = 6; i < length; i += 1) {
buf[i + 148] = checksum.charCodeAt(i);
}
self.fields.forEach(function(value) {
data[value.field] = buffer.toString('utf8', offset, offset + (value.length - 1)).replace(/\u0000.*/, '');
offset += value.length;
});
buf[154] = 0;
buf[155] = 0x20;
delete data.padding;
return buf;
};
return data;
},
HeaderTarFile.prototype.toObject = function(buf) {
var self = this;
createChecksum: function(buffer) {
var checksum = 0;
for (var i = 0, length = buffer.length; i < length; i += 1) {
checksum += buffer[i];
}
var data = {};
var offset = 0;
var result;
checksum = checksum.toString(8);
while (checksum.length < 6) {
checksum = '0' + checksum;
self.fields.forEach(function(value) {
result = buf.toString('utf8', offset, offset + value.len).replace(/\0+$/, '');
if (value.field === 'ustar') {
result = (result === 'ustar');
} else if (value.field === 'mtime') {
result = self._parseNumeric(result);
data['date'] = util.convertDateTimeEpoch(result);
} else if (value.type === 'number') {
result = self._parseNumeric(result);
}
return checksum;
data[value.field] = result;
offset += value.len;
});
delete data.padding;
return data;
};
HeaderTarFile.prototype._normalize = function(data) {
data.name = util.sanitizeFilePath(data.name);
data.mode = typeof data.mode === 'number' ? data.mode : 0664;
data.mode = data.mode & 0777;
data.uid = typeof data.uid === 'number' ? data.uid : 0;
data.gid = typeof data.gid === 'number' ? data.gid : 0;
if (typeof data.mtime !== 'number') {
data.date = util.dateify(data.date);
data.mtime = util.epochDateTime(data.date);
} else {
data.date = util.convertDateTimeEpoch(data.mtime);
}
var pathParts = this._splitFilePath(data.name);
data.name = pathParts[0];
data.prefix = pathParts[1];
return data;
};
HeaderTarFile.prototype._createChecksum = function(buf) {
var checksum = 0;
for (var i = 0, length = buf.length; i < length; i += 1) {
checksum += buf[i];
}
checksum = checksum.toString(8);
while (checksum.length < 6) {
checksum = '0' + checksum;
}
return checksum;
};
var MAXNUM = {
12: 077777777777,
11: 07777777777,
8: 07777777,
7: 0777777
};
HeaderTarFile.prototype._prepNumeric = function(num, len) {
num = num || 0;
var max = MAXNUM[len] || 0;
if (num > max || num < 0) {
// need an extended header if negative or too big. someday just not today..
}
var str = Math.floor(num).toString(8);
if (num < MAXNUM[len - 1]) {
str += ' ';
}
if (str.length < len) {
str = util.repeat('0', len - str.length) + str;
}
return str;
};
HeaderTarFile.prototype._parseNumeric = function(str) {
var res = parseInt(str.trim(), 8);
return isNaN(res) ? null : res;
};
HeaderTarFile.prototype._splitFilePath = function(filepath) {
var fileName = filepath;
var filePrefix = '';
var sepIndex;
if (filepath.length > 100 && filepath.length <= 255) {
sepIndex = filepath.substring(0, 155).lastIndexOf('/');
if (sepIndex !== -1) {
filePrefix = filepath.substring(0, sepIndex);
fileName = filepath.substring(sepIndex + 1);
}
}
return [fileName, filePrefix];
};
var headers = {
file: new HeaderTarFile()
};
var encode = exports.encode = function(type, data) {
if (typeof headers[type].toBuffer === 'function') {
return headers[type].toBuffer(data);
} else {
return false;
if (!headers[type] || typeof headers[type].toBuffer !== 'function') {
throw new Error('Unknown encode type');
}
return headers[type].toBuffer(data);
};
var decode = exports.decode = function(type, data) {
if (typeof headers[type].toObject === 'function') {
return headers[type].toObject(data);
} else {
return false;
var decode = exports.decode = function(type, buf) {
if (!headers[type] || typeof headers[type].toObject !== 'function') {
throw new Error('Unknown decode type');
}
};
return headers[type].toObject(buf);
};
exports.file = HeaderTarFile;

@@ -9,208 +9,176 @@ /**

var headers = {};
var inherits = require('util').inherits;
headers.file = {
fields: [
{'field': 'signature', 'length': 4, 'type': 'UInt32LE', 'default': 0x04034b50},
{'field': 'versionNeededToExtract', 'length': 2, 'type': 'UInt16LE'},
{'field': 'flags', 'length': 2, 'type': 'UInt16LE'},
{'field': 'compressionMethod', 'length': 2, 'type': 'UInt16LE'},
{'field': 'lastModifiedDate', 'length': 4, 'type': 'UInt32LE'},
{'field': 'crc32', 'length': 4, 'type': 'Int32LE', 'default': 0},
{'field': 'compressedSize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'uncompressedSize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'filenameLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'extraFieldLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'name', 'length': -1, 'type': 'string'},
{'field': 'extraField', 'length': -1, 'type': 'string'}
],
function HeaderZip() {
this.bufferSize = 0;
this.fields = [];
}
toBuffer: function(data) {
var self = this;
HeaderZip.prototype.toBuffer = function(data) {
var buf = new Buffer(this.bufferSize);
var offset = 0;
var val;
var fallback;
var buffer = new Buffer(1024);
var offset = 0;
var val;
var fallback;
data = this._normalize(data);
self.fields.forEach(function(value) {
fallback = (value.type === 'string') ? '' : 0;
val = data[value.field] || value.default || fallback;
this.fields.forEach(function(value) {
fallback = (value.type === 'string') ? '' : 0;
val = data[value.field] || value.def || fallback;
if (value.field === 'name') {
value.length = buffer.write(val, offset);
buffer.writeUInt16LE(value.length, 26);
} else if (value.field === 'extraField') {
value.length = (val.length > 0) ? buffer.write(val, offset) : 0;
buffer.writeUInt16LE(value.length, 28);
} else if (value.type === 'UInt32LE') {
buffer.writeUInt32LE(val, offset);
} else if (value.type === 'Int32LE') {
buffer.writeInt32LE(val, offset);
} else if (value.type === 'UInt16LE') {
buffer.writeUInt16LE(val, offset);
} else {
buffer.write(val, offset);
}
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);
} else if (val.length > 0) {
buf.write(val, offset);
}
offset += value.length;
});
offset += value.len;
});
return buffer.slice(0, offset);
}
return buf.slice(0, offset);
};
headers.fileDescriptor = {
fields: [
{'field': 'signature', 'length': 4, 'type': 'UInt32LE', 'default': 0x08074b50},
{'field': 'crc32', 'length': 4, 'type': 'Int32LE'},
{'field': 'compressedSize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'uncompressedSize', 'length': 4, 'type': 'UInt32LE'}
],
HeaderZip.prototype.toObject = function(buf) {
var data = {};
var offset = 0;
toBuffer: function(data) {
var self = this;
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);
} else {
data[value.field] = buf.toString(null, offset, value.len);
}
var buffer = new Buffer(16);
var offset = 0;
var val;
offset += value.len;
});
self.fields.forEach(function(value) {
val = data[value.field] || value.default || 0;
return data;
};
if (value.type === 'UInt32LE') {
buffer.writeUInt32LE(val, offset);
} else if (value.type === 'Int32LE') {
buffer.writeInt32LE(val, offset);
}
HeaderZip.prototype._normalize = function(data) {
if (data.name) {
data.filenameLength = data.name.length;
}
offset += value.length;
});
if (data.comment) {
data.commentLength = data.comment.length;
}
return buffer;
if (data.extraField) {
data.extraFieldLength = data.extraField.length;
}
return data;
};
headers.centralHeader = {
fields: [
{'field': 'signature', 'length': 4, 'type': 'UInt32LE', 'default': 0x02014b50},
{'field': 'versionMadeBy', 'length': 2, 'type': 'UInt16LE'},
{'field': 'versionNeededToExtract', 'length': 2, 'type': 'UInt16LE'},
{'field': 'flags', 'length': 2, 'type': 'UInt16LE'},
{'field': 'compressionMethod', 'length': 2, 'type': 'UInt16LE'},
{'field': 'lastModifiedDate', 'length': 4, 'type': 'UInt32LE'},
{'field': 'crc32', 'length': 4, 'type': 'Int32LE'},
{'field': 'compressedSize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'uncompressedSize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'filenameLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'extraFieldLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'commentLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'diskNumberStart', 'length': 2, 'type': 'UInt16LE'},
{'field': 'internalFileAttributes', 'length': 2, 'type': 'UInt16LE'},
{'field': 'externalFileAttributes', 'length': 4, 'type': 'UInt32LE'},
{'field': 'offset', 'length': 4, 'type': 'UInt32LE'},
{'field': 'name', 'length': -1, 'type': 'string'},
{'field': 'extraField', 'length': -1, 'type': 'string'},
{'field': 'comment', 'length': -1, 'type': 'string'}
],
function HeaderZipFile() {
HeaderZip.call(this);
toBuffer: function(data) {
var self = this;
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'}
];
}
inherits(HeaderZipFile, HeaderZip);
var buffer = new Buffer(1024);
var offset = 0;
var val;
var fallback;
function HeaderZipFileDescriptor() {
HeaderZip.call(this);
var nameLength;
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'}
];
}
inherits(HeaderZipFileDescriptor, HeaderZip);
self.fields.forEach(function(value) {
fallback = (value.type === 'string') ? '' : 0;
val = data[value.field] || value.default || fallback;
function HeaderZipCentralDirectory() {
HeaderZip.call(this);
if (value.field === 'name') {
value.length = buffer.write(val, offset);
buffer.writeUInt16LE(value.length, 28);
} else if (value.field === 'extraField') {
value.length = (val.length > 0) ? buffer.write(val, offset) : 0;
buffer.writeUInt16LE(value.length, 30);
} else if (value.field === 'comment') {
value.length = (val.length > 0) ? buffer.write(val, offset) : 0;
buffer.writeUInt16LE(value.length, 32);
} else if (value.type === 'UInt32LE') {
buffer.writeUInt32LE(val, offset);
} else if (value.type === 'Int32LE') {
buffer.writeInt32LE(val, offset);
} else if (value.type === 'UInt16LE') {
buffer.writeUInt16LE(val, offset);
} else {
buffer.write(val, offset);
}
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'}
];
}
inherits(HeaderZipCentralDirectory, HeaderZip);
offset += value.length;
});
function HeaderZipCentralFooter() {
HeaderZip.call(this);
return buffer.slice(0, offset);
}
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'}
];
}
inherits(HeaderZipCentralFooter, HeaderZip);
var headers = {
file: new HeaderZipFile(),
fileDescriptor: new HeaderZipFileDescriptor(),
centralDirectory: new HeaderZipCentralDirectory(),
centralFooter: new HeaderZipCentralFooter()
};
headers.centralFooter = {
fields: [
{'field': 'signature', 'length': 4, 'type': 'UInt32LE', 'default': 0x06054b50},
{'field': 'diskNumber', 'length': 2, 'type': 'UInt16LE'},
{'field': 'diskNumberStart', 'length': 2, 'type': 'UInt16LE'},
{'field': 'directoryRecordsDisk', 'length': 2, 'type': 'UInt16LE'},
{'field': 'directoryRecords', 'length': 2, 'type': 'UInt16LE'},
{'field': 'directorySize', 'length': 4, 'type': 'UInt32LE'},
{'field': 'directoryOffset', 'length': 4, 'type': 'UInt32LE'},,
{'field': 'commentLength', 'length': 2, 'type': 'UInt16LE'},
{'field': 'comment', 'length': -1, 'type': 'string'}
],
var encode = exports.encode = function(type, data) {
if (!headers[type] || typeof headers[type].toBuffer !== 'function') {
throw new Error('Unknown encode type');
}
toBuffer: function(data) {
var self = this;
return headers[type].toBuffer(data);
};
var buffer = new Buffer(512);
var offset = 0;
var val;
var fallback;
self.fields.forEach(function(value) {
fallback = (value.type === 'string') ? '' : 0;
val = data[value.field] || value.default || fallback;
if (value.field === 'comment') {
value.length = (val.length > 0) ? buffer.write(val, offset) : 0;
buffer.writeUInt16LE(value.length, 20);
} else if (value.type === 'UInt32LE') {
buffer.writeUInt32LE(val, offset);
} else if (value.type === 'Int32LE') {
buffer.writeInt32LE(val, offset);
} else if (value.type === 'UInt16LE') {
buffer.writeUInt16LE(val, offset);
} else {
buffer.write(val, offset);
}
offset += value.length;
});
return buffer.slice(0, offset);
var decode = exports.decode = function(type, buf) {
if (!headers[type] || typeof headers[type].toObject !== 'function') {
throw new Error('Unknown decode type');
}
};
var encode = exports.encode = function(type, data) {
if (typeof headers[type].toBuffer === 'function') {
return headers[type].toBuffer(data);
} else {
return false;
}
return headers[type].toObject(buf);
};
var decode = exports.decode = function(type, data) {
if (typeof headers[type].toObject === 'function') {
return headers[type].toObject(data);
} else {
return false;
}
};
exports.file = HeaderZipFile;
exports.fileDescriptor = HeaderZipFileDescriptor;
exports.centralDirectory = HeaderZipCentralDirectory;
exports.centralFooter = HeaderZipCentralFooter;

@@ -72,2 +72,8 @@ /**

util.convertDateTimeEpoch = function(input) {
input = input * 1000;
return new Date(input);
};
util.convertDateTimeOctal = function(input) {

@@ -80,13 +86,13 @@ input = parseInt(input, 8) * 1000;

util.dateify = function(dateish) {
var date;
dateish = dateish || new Date();
if (dateish instanceof Date) {
date = dateish;
dateish = dateish;
} else if (typeof dateish === 'string') {
date = new Date(dateish);
dateish = new Date(dateish);
} else {
date = new Date();
dateish = new Date();
}
return date;
return dateish;
};

@@ -150,2 +156,8 @@

util.epochDateTime = function(d) {
d = (d instanceof Date) ? d : new Date();
return Math.round(d / 1000);
};
util.keys = function(object) {

@@ -201,2 +213,3 @@ if (!util.isObject(object)) {

util.sanitizeFilePath = function(filepath) {
filepath = filepath || '';
filepath = path.normalize(filepath);

@@ -212,4 +225,61 @@ filepath = util.unixifyPath(filepath);

util.scanBuffer = function(buf, search, offset) {
if (!Buffer.isBuffer(buf)) {
return false;
}
var origBufLength = buf.length;
var negative = false;
var wasOffset = false;
if (offset) {
if (offset < 0) {
offset = offset * -1;
negative = true;
}
if (offset <= origBufLength) {
if (negative) {
offset = offset * -1;
}
wasOffset = true;
buf = buf.slice(offset);
}
}
if (typeof search === 'string') {
search = new Buffer(search);
} else if (!Buffer.isBuffer(search)) {
return false;
}
// simple but slow string search
for (var i = 0; i <= buf.length - search.length + 1; i++) {
for (var j = 0; j < search.length && buf[i + j] === search[j]; j++);
if (j === search.length) {
if (wasOffset) {
return origBufLength - (buf.length - i);
}
return i;
}
}
return false;
};
util.scanBufferUInt32LE = function(buf, search, offset) {
if (!search) {
return false;
}
var searchBuf = new Buffer(4);
searchBuf.writeUInt32LE(search, 0);
return util.scanBuffer(buf, searchBuf, offset);
};
util.unixifyPath = function(filepath) {
return filepath.replace(/\\/g, '/');
};
{
"name": "archiver",
"version": "0.4.5",
"version": "0.4.6",
"description": "Creates Archives (ZIP) via Node Streams.",

@@ -35,5 +35,5 @@ "homepage": "https://github.com/ctalkington/node-archiver",

"devDependencies": {
"chai": "~1.6.0",
"mocha": "~1.9.0",
"rimraf": "~2.1.4",
"chai": "~1.7.1",
"mocha": "~1.11.0",
"rimraf": "~2.2.0",
"mkdirp": "~0.3.5",

@@ -40,0 +40,0 @@ "stream-bench": "~0.1.2"

@@ -1,2 +0,2 @@

# Archiver v0.4.5 [![Build Status](https://secure.travis-ci.org/ctalkington/node-archiver.png?branch=master)](http://travis-ci.org/ctalkington/node-archiver)
# Archiver v0.4.6 [![Build Status](https://secure.travis-ci.org/ctalkington/node-archiver.png?branch=master)](http://travis-ci.org/ctalkington/node-archiver)

@@ -3,0 +3,0 @@ Creates Archives (Zip, Tar) via Node Streams. Depends on Node's built-in zlib module for compression available since version 0.6.3.

@@ -38,3 +38,3 @@ /*global before,describe,it */

testStream.on('close', function() {
assert.equal(testStream.digest, 'e87af3cdd4b01bb72ebab46baa97ee1eb814a1d3');
assert.equal(testStream.digest, '3a8a9ff17087129cc05dc88be86573ecf3f9ca56');
done();

@@ -55,3 +55,3 @@ });

testStream.on('close', function() {
assert.equal(testStream.digest, 'da02a931d670f725c0de20ef30b112b53d149a3d');
assert.equal(testStream.digest, '3e3271c503deeba9abe5031df6bca636f1eb115b');
done();

@@ -74,3 +74,3 @@ });

testStream.on('close', function() {
assert.equal(testStream.digest, '76a580762b214851ec9c45a2915356b005ec068b');
assert.equal(testStream.digest, '54a94b8b72eac5f6acf5c1ec84aa2e69969267ca');
done();

@@ -97,3 +97,3 @@ });

testStream.on('close', function() {
assert.equal(testStream.digest, '333f843838ba5ee7727b3cc8afa017cab3d70d72');
assert.equal(testStream.digest, 'fb620048e1bceefb0be06d3f18ea00929951b105');
done();

@@ -114,3 +114,3 @@ });

testStream.on('close', function() {
assert.equal(testStream.digest, '0f2cfcb20ebc1958c2a9e78ad9d969fb7cae19df');
assert.equal(testStream.digest, '1437ef391a7c2c0de180bddff21b98c2f9778331');
done();

@@ -127,2 +127,23 @@ });

});
it('should use prefix for deep paths', function(done) {
var archive = archiver('tar');
var testStream = new WriteHashStream('tmp/feature-prefix.tar');
testStream.on('close', function() {
assert.equal(testStream.digest, 'aeb2496b2bd7458931ba942dba2b4bf28cbc187c');
done();
});
archive.pipe(testStream);
var deepPath = 'vvmbtqhysigpregbdrc/pyqaznbelhppibmbykz/';
deepPath += 'qcbclwjhktiazmhnsjt/kpsgdfyfkarbvnlinrt/';
deepPath += 'holobndxfccyecblhcc/';
deepPath += deepPath;
archive
.append('deep path', { name: deepPath + 'file.txt', date: testDate })
.finalize();
});
});

@@ -129,0 +150,0 @@

@@ -12,2 +12,3 @@ /*global before,describe,it */

var testDate = new Date('Jan 03 2013 14:26:38 GMT');
var testDateEpoch = 1357223198;

@@ -17,15 +18,4 @@ describe('headers', function() {

describe('tar', function() {
var fileObj = {
name: 'test.txt',
date: testDate,
comment: '',
gid: '0000000',
mode: '0000777',
mtime: '12071312436',
uid: '0000000',
type: '0',
size: '00000000023'
};
var fileFixture = fs.readFileSync('test/fixtures/headers/tar-file.bin');
var filePrefixFixture = fs.readFileSync('test/fixtures/headers/tar-fileprefix.bin');

@@ -35,3 +25,10 @@ describe('#encode(type, object)', function() {

describe('type->file', function() {
var actual = tar.encode('file', fileObj);
var actual = tar.encode('file', {
name: 'test.txt',
date: testDate,
mode: 0644,
size: 23,
owner: 'test',
group: 'test'
});

@@ -47,4 +44,21 @@ it('should return an instance of Buffer', function() {

it('should match provided fixture', function() {
assert.equal(actual.toString(), fileFixture.toString());
//fs.writeFileSync('test/fixtures/headers/tar-file.bin', actual);
assert.deepEqual(actual.toString(), fileFixture.toString());
});
it('should use prefix for deep paths', function() {
var deepPath = 'vvmbtqhysigpregbdrc/pyqaznbelhppibmbykz/';
deepPath += 'qcbclwjhktiazmhnsjt/kpsgdfyfkarbvnlinrt/';
deepPath += 'holobndxfccyecblhcc/';
deepPath += deepPath;
var actual = tar.encode('file', {
name: deepPath + 'test.txt',
date: testDate,
size: 23
});
//fs.writeFileSync('test/fixtures/headers/tar-fileprefix.bin', actual);
assert.deepEqual(actual.toString(), filePrefixFixture.toString());
});
});

@@ -59,5 +73,28 @@

it('should match provided checksum', function() {
assert.equal(actual.checksum, '007425');
it('should return an object', function() {
assert.isObject(actual);
});
it('should properly decode pre-posix attributes', function() {
assert.equal(actual.name, 'test.txt');
assert.equal(actual.uid, 0);
assert.equal(actual.gid, 0);
assert.equal(actual.mode, 420);
assert.equal(actual.size, 23);
assert.deepEqual(actual.date, testDate);
assert.equal(actual.mtime, testDateEpoch);
assert.equal(actual.checksum, 5730);
assert.equal(actual.type, '0');
assert.equal(actual.linkName, '');
});
it('should properly decode ustar attributes', function() {
assert.equal(actual.ustar, true);
assert.equal(actual.ustarVersion, '00');
assert.equal(actual.owner, 'test');
assert.equal(actual.group, 'test');
assert.equal(actual.devMajor, 0);
assert.equal(actual.devMinor, 0);
assert.equal(actual.prefix, '');
});
});

@@ -67,56 +104,50 @@

});
describe('HeaderTarFile', function() {
var HeaderTarFile = tar.file;
var thing = new HeaderTarFile();
describe('#_parseNumeric(num, len)', function() {
it('should convert octal strings to numeric values', function() {
assert.equal(thing._parseNumeric('21'), 17);
assert.equal(thing._parseNumeric('0021'), 17);
});
});
describe('zip', function() {
var fileObj = {
name: 'test.txt',
date: testDate,
comment: '',
mode: null,
store: true,
lastModifiedDate: 1109619539,
versionMadeBy: 20,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
uncompressedSize: 0,
compressedSize: 0,
offset: 0
};
describe('#_prepNumeric(num, len)', function() {
it('should convert numeric values to octal strings', function() {
assert.equal(thing._prepNumeric(17, 2), '21');
var fileDescriptorObj = {
crc32: 585446183,
uncompressedSize: 19,
compressedSize: 19,
};
});
var centralHeaderObj = {
name: 'test.txt',
date: testDate,
store: true,
comment: '',
mode: null,
lastModifiedDate: 1109619539,
versionMadeBy: 20,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
uncompressedSize: 19,
compressedSize: 19,
offset: 0,
crc32: 585446183
};
it('should zero pad when needed', function() {
assert.equal(thing._prepNumeric(17, 4), '0021');
});
});
var centralFooterObj = {
directoryRecordsDisk: 1,
directoryRecords: 1,
directorySize: 56,
directoryOffset: 73,
comment: ''
};
describe('#_splitFilePath(filepath)', function() {
it('should split a filepath into a name and prefix', function() {
var deepPath = 'vvmbtqhysigpregbdrc/pyqaznbelhppibmbykz/';
deepPath += 'qcbclwjhktiazmhnsjt/kpsgdfyfkarbvnlinrt/';
deepPath += 'holobndxfccyecblhcc/';
deepPath += deepPath;
var actual = thing._splitFilePath(deepPath + 'file.txt');
assert.deepEqual(actual, [
"qcbclwjhktiazmhnsjt/kpsgdfyfkarbvnlinrt/holobndxfccyecblhcc/file.txt",
"vvmbtqhysigpregbdrc/pyqaznbelhppibmbykz/qcbclwjhktiazmhnsjt/kpsgdfyfkarbvnlinrt/" +
"holobndxfccyecblhcc/vvmbtqhysigpregbdrc/pyqaznbelhppibmbykz"
]);
});
});
});
});
describe('zip', function() {
var fileFixture = fs.readFileSync('test/fixtures/headers/zip-file.bin');
var fileDescriptorFixture = fs.readFileSync('test/fixtures/headers/zip-filedescriptor.bin');
var centralHeaderFixture = fs.readFileSync('test/fixtures/headers/zip-centralheader.bin');
var centralDirectoryFixture = fs.readFileSync('test/fixtures/headers/zip-centralheader.bin');
var centralFooterFixture = fs.readFileSync('test/fixtures/headers/zip-centralfooter.bin');

@@ -127,3 +158,18 @@

describe('type->file', function() {
var actual = zip.encode('file', fileObj);
var actual = zip.encode('file', {
name: 'test.txt',
filenameLength: 8,
date: testDate,
comment: '',
mode: null,
store: true,
lastModifiedDate: 1109619539,
versionMadeBy: 20,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
uncompressedSize: 0,
compressedSize: 0,
offset: 0
});

@@ -140,3 +186,7 @@ it('should return an instance of Buffer', function() {

describe('type->fileDescriptor', function() {
var actual = zip.encode('fileDescriptor', fileDescriptorObj);
var actual = zip.encode('fileDescriptor', {
crc32: 585446183,
uncompressedSize: 19,
compressedSize: 19,
});

@@ -152,4 +202,20 @@ it('should return an instance of Buffer', function() {

describe('type->centralHeader', function() {
var actual = zip.encode('centralHeader', centralHeaderObj);
describe('type->centralDirectory', function() {
var actual = zip.encode('centralDirectory', {
name: 'test.txt',
filenameLength: 8,
date: testDate,
store: true,
comment: '',
mode: null,
lastModifiedDate: 1109619539,
versionMadeBy: 20,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
uncompressedSize: 19,
compressedSize: 19,
offset: 0,
crc32: 585446183
});

@@ -161,3 +227,3 @@ it('should return an instance of Buffer', function() {

it('should match provided fixture', function() {
assert.deepEqual(actual, centralHeaderFixture);
assert.deepEqual(actual, centralDirectoryFixture);
});

@@ -167,3 +233,9 @@ });

describe('type->centralFooter', function() {
var actual = zip.encode('centralFooter', centralFooterObj);
var actual = zip.encode('centralFooter', {
directoryRecordsDisk: 1,
directoryRecords: 1,
centralDirectorySize: 56,
centralDirectoryOffset: 73,
comment: ''
});

@@ -183,2 +255,98 @@ it('should return an instance of Buffer', function() {

describe('type->file', function() {
var actual = zip.decode('file', fileFixture);
it('should return an object', function() {
assert.isObject(actual);
});
it('should match provided fixture', function() {
assert.deepEqual(actual, {
signature: 67324752,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
lastModifiedDate: 1109619539,
crc32: 0,
compressedSize: 0,
uncompressedSize: 0,
filenameLength: 8,
extraFieldLength: 0,
name: 'test.txt',
extraField: null
});
});
});
describe('type->fileDescriptor', function() {
var actual = zip.decode('fileDescriptor', fileDescriptorFixture);
it('should return an object', function() {
assert.isObject(actual);
});
it('should match provided fixture', function() {
assert.deepEqual(actual, {
signature: 134695760,
crc32: 585446183,
uncompressedSize: 19,
compressedSize: 19,
});
});
});
describe('type->centralDirectory', function() {
var actual = zip.decode('centralDirectory', centralDirectoryFixture);
it('should return an object', function() {
assert.isObject(actual);
});
it('should match provided fixture', function() {
assert.deepEqual(actual, {
signature: 33639248,
versionMadeBy: 20,
versionNeededToExtract: 20,
flags: 2056,
compressionMethod: 0,
lastModifiedDate: 1109619539,
crc32: 585446183,
compressedSize: 19,
uncompressedSize: 19,
filenameLength: 8,
extraFieldLength: 0,
commentLength: 0,
diskNumberStart: 0,
internalFileAttributes: 0,
externalFileAttributes: 0,
offset: 0,
name: 'test.txt',
extraField: null,
comment: null
});
});
});
describe('type->centralFooter', function() {
var actual = zip.decode('centralFooter', centralFooterFixture);
it('should return an object', function() {
assert.isObject(actual);
});
it('should match provided fixture', function() {
assert.deepEqual(actual, {
signature: 101010256,
diskNumber: 0,
diskNumberStart: 0,
directoryRecordsDisk: 1,
directoryRecords: 1,
centralDirectorySize: 56,
centralDirectoryOffset: 73,
commentLength: 0,
comment: null
});
});
});
});

@@ -185,0 +353,0 @@

@@ -19,5 +19,6 @@ /*global describe,it */

var testDate = new Date('Jan 03 2013 14:26:38 GMT');
var testDateOctal = 12071312436;
var testDateDos = 1109607251;
var testDateDosUTC = 1109619539;
var testDateEpoch = 1357223198;
var testDateOctal = 12071312436;

@@ -153,2 +154,8 @@ var testTimezoneOffset = testDate.getTimezoneOffset();

describe('convertDateTimeEpoch(input)', function() {
it('should convert epoch input into an instance of Date', function() {
assert.deepEqual(utils.convertDateTimeEpoch(testDateEpoch), testDate);
});
});
describe('convertDateTimeOctal(input)', function() {

@@ -240,2 +247,8 @@ it('should convert octal input into an instance of Date', function() {

describe('epochDateTime(date)', function() {
it('should convert date into its epoch representation', function() {
assert.equal(utils.epochDateTime(testDate), testDateEpoch);
});
});
describe('isStream(source)', function() {

@@ -242,0 +255,0 @@ it('should return true if source is a stream', function() {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc