Comparing version 1.1.3 to 1.1.4
@@ -6,3 +6,3 @@ { | ||
"keywords": ["tar", "untar", "asynchronous", "stream", "async", "chunk", "chunked"], | ||
"version": "1.1.3", | ||
"version": "1.1.4", | ||
"repository": { | ||
@@ -9,0 +9,0 @@ "type": "git", |
177
tar.js
@@ -1,2 +0,1 @@ | ||
/*jshint strict:true node:true es5:true onevar:true laxcomma:true laxbreak:true*/ | ||
(function () { | ||
@@ -7,4 +6,3 @@ "use strict"; | ||
Stream = require('stream').Stream, | ||
EventEmitter = require('events').EventEmitter, | ||
Header = require("./header"), | ||
header = require("./header"), | ||
utils = require("./utils"), | ||
@@ -48,11 +46,2 @@ recordSize = 512, | ||
function updateChecksum(key) { | ||
/*jshint validthis:true*/ | ||
var i, value = this.data[key], length; | ||
for (i = 0, length = value.length; i < length; i += 1) { | ||
this.checksum += value.charCodeAt(i); | ||
} | ||
} | ||
Tar.prototype.append = function (filepath, input, opts, callback) { | ||
@@ -67,45 +56,7 @@ var data, | ||
tape = this, | ||
treatAsBuffer, | ||
inputStream, | ||
realInput, | ||
headerContainer, | ||
extraBytes, | ||
i, | ||
length, | ||
headerBuf; | ||
function emitFakeStream() { | ||
inputStream.emit('data', realInput); | ||
inputStream.emit('end', realInput); | ||
} | ||
function addChunkToTar(chunk) { | ||
tape.emit('data', chunk); | ||
tape.written += chunk.length; | ||
} | ||
function checkQueue() { | ||
tape.processing = false; | ||
if (typeof callback === 'function') { | ||
callback(); | ||
} | ||
if (!queue.length) { | ||
return; | ||
} | ||
var elem = queue.splice(0, 1)[0]; | ||
tape.append(elem.filepath, elem.input, elem.opts, elem.cb); | ||
} | ||
function padTarAndEnd() { | ||
var extraBytes = recordSize - (size % recordSize || recordSize) | ||
; | ||
addChunkToTar(utils.clean(extraBytes)); | ||
process.nextTick(checkQueue); | ||
} | ||
// callback mangling | ||
if (typeof opts === 'function') { | ||
@@ -116,10 +67,13 @@ callback = opts; | ||
// If we're in the middle of something, wait until we | ||
// finish to queue up the next | ||
if (typeof callback !== 'function') { | ||
callback = function (err, data) { | ||
if (err) { | ||
throw err; | ||
} | ||
return data; | ||
}; | ||
} | ||
if (this.processing || queue.length) { | ||
if ('function' === typeof input.pause) { | ||
input.pause(); | ||
} | ||
// TODO check for drain before resuming | ||
queue.push({ | ||
@@ -131,3 +85,2 @@ filepath: filepath, | ||
}); | ||
return; | ||
@@ -138,8 +91,17 @@ } | ||
mode = opts.mode || parseInt('777', 8) & 0xfff; | ||
mtime = opts.mtime || parseInt(Date.now() / 1000, 10); | ||
uid = opts.uid || 0; | ||
gid = opts.gid || 0; | ||
size = opts.size || input.length || 0; | ||
mode = typeof opts.mode === 'number' ? opts.mode : parseInt('777', 8) & 0xfff; | ||
mtime = typeof opts.mtime === 'number' ? opts.mtime : parseInt(+new Date() / 1000); | ||
uid = typeof opts.uid === 'number' ? opts.uid : 0; | ||
gid = typeof opts.gid === 'number' ? opts.gid : 0; | ||
size = typeof opts.size === 'number' ? opts.size : input.length; | ||
// if you give me a stream, you must tell me how big it is | ||
// since the header comes first, the only other solution is to | ||
// cache the entire file before writing it out to a stream, | ||
// which completely invalidates the purpose of a stream | ||
if (input instanceof Stream && (typeof size !== 'number' || size < 0)) { | ||
console.log('Error:', size); | ||
return callback(new Error('Streams must supply the total size of the stream.')); | ||
} | ||
data = { | ||
@@ -154,3 +116,3 @@ filename: this.consolidate ? path.basename(filepath) : filepath, | ||
type: '0', // just a file | ||
ustar: 'ustar ', | ||
ustar: 'ustar ', | ||
owner: '', | ||
@@ -164,44 +126,65 @@ group: '' | ||
// format the header without the checksum | ||
headerBuf = header.format(data); | ||
// calculate the checksum | ||
headerContainer = { data: data, checksum: 0 }; | ||
Object.keys(data).forEach(updateChecksum, headerContainer); | ||
checksum = headerContainer.checksum; | ||
checksum = 0; | ||
for (i = 0, length = headerBuf.length; i < length; i += 1) { | ||
checksum += headerBuf[i]; | ||
} | ||
data.checksum = utils.pad(checksum, 6) + "\u0000 "; | ||
// pad the checksum | ||
checksum = checksum.toString(8); | ||
while (checksum.length < 6) { | ||
checksum = '0' + checksum; | ||
} | ||
headerBuf = Header.format(data); | ||
// write the checksum into the header | ||
for (i = 0, length = 6; i < length; i += 1) { | ||
headerBuf[i + 148] = checksum.charCodeAt(i); | ||
} | ||
headerBuf[154] = 0; | ||
headerBuf[155] = 0x20; | ||
// and write it out to the stream | ||
this.emit('data', headerBuf); | ||
this.written += headerBuf.length; | ||
// a step towards making this browser-usable code | ||
if ('undefined' !== typeof Buffer) { | ||
if (input instanceof Buffer) { | ||
treatAsBuffer = true; | ||
} | ||
if ('string' === typeof input) { | ||
// get correct number of bytes with unicode chars | ||
input = new Buffer(input); | ||
} | ||
} | ||
// if it's a string/Buffer, we can just write it out to the stream | ||
if (typeof input === 'string' || input instanceof Buffer) { | ||
this.emit('data', input); | ||
this.written += input.length; | ||
// TODO get correct number of bytes for unicode characters | ||
// when the environment isn't NodeJS (no Buffer) | ||
if (typeof input === 'string' || treatAsBuffer) { | ||
inputStream = new EventEmitter(); | ||
extraBytes = recordSize - (size % recordSize || recordSize); | ||
this.emit('data', utils.clean(recordSize - (size % recordSize))); | ||
this.written += extraBytes; | ||
// emitFakeStream uses realInput | ||
realInput = input; | ||
process.nextTick(emitFakeStream); | ||
return callback(); | ||
} else { | ||
inputStream = input; | ||
} | ||
// otherwise we need to do it asynchronously | ||
this.processing = true; | ||
tape.processing = true; | ||
input.on('data', function (chunk) { | ||
tape.emit('data', chunk); | ||
tape.written += chunk.length; | ||
}); | ||
if ('function' === typeof inputStream.resume) { | ||
inputStream.resume(); | ||
} | ||
input.on('end', function () { | ||
extraBytes = recordSize - (size % recordSize || recordSize); | ||
tape.emit('data', utils.clean(extraBytes)); | ||
tape.written += extraBytes; | ||
inputStream.on('data', addChunkToTar); | ||
inputStream.on('end', padTarAndEnd); | ||
tape.processing = false; | ||
if (queue.length > 0) { | ||
process.nextTick(function () { | ||
var job = queue.shift(); | ||
tape.append(job.filepath, job.input, job.opts, job.cb); | ||
}); | ||
} | ||
return callback(); | ||
}); | ||
} | ||
}; | ||
@@ -208,0 +191,0 @@ |
12
utils.js
@@ -1,2 +0,1 @@ | ||
/*jshint strict:true node:true es5:true onevar:true laxcomma:true laxbreak:true*/ | ||
(function () { | ||
@@ -6,8 +5,7 @@ "use strict"; | ||
function clean(length) { | ||
var buf = new Buffer(length) | ||
; | ||
buf.fill(0); | ||
return buf; | ||
var i, buffer = new Buffer(length); | ||
for (i = 0; i < length; i += 1) { | ||
buffer[i] = 0; | ||
} | ||
return buffer; | ||
} | ||
@@ -14,0 +12,0 @@ |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
12804
485
1