diff --git a/.travis.yml b/.travis.yml index 6e5919d..cc4dba2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: node_js node_js: + - "0.8" - "0.10" diff --git a/extract.js b/extract.js index f6e7b51..6f3d3c6 100644 --- a/extract.js +++ b/extract.js @@ -3,6 +3,9 @@ var util = require('util'); var bl = require('bl'); var headers = require('./headers'); +var Writable = stream.Writable || require('readable-stream').Writable; +var PassThrough = stream.PassThrough || require('readable-stream').PassThrough; + var noop = function() {}; var overflow = function(size) { @@ -11,7 +14,7 @@ var overflow = function(size) { }; var emptyStream = function() { - var s = new stream.PassThrough(); + var s = new PassThrough(); s.end(); return s; }; @@ -24,7 +27,7 @@ var mixinPax = function(header, pax) { var Extract = function(opts) { if (!(this instanceof Extract)) return new Extract(opts); - stream.Writable.call(this, opts); + Writable.call(this, opts); this._buffer = bl(); this._missing = 0; @@ -99,7 +102,7 @@ var Extract = function(opts) { return; } - self._stream = new stream.PassThrough(); + self._stream = new PassThrough(); self.emit('entry', header, self._stream, onunlock); self._parse(header.size, onstreamend); @@ -109,7 +112,7 @@ var Extract = function(opts) { this._parse(512, onheader); }; -util.inherits(Extract, stream.Writable); +util.inherits(Extract, Writable); Extract.prototype.destroy = function(err) { if (this._destroyed) return; diff --git a/headers.js b/headers.js index eeb2842..e4d828f 100644 --- a/headers.js +++ b/headers.js @@ -2,6 +2,16 @@ var ZEROS = '0000000000000000000'; var ZERO_OFFSET = '0'.charCodeAt(0); var USTAR = 'ustar00'; +var clamp = function(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +}; + var toType = function(flag) { switch (flag) { case 0: @@ -19,7 +29,7 @@ var toType = function(flag) { case 6: return 'fifo'; case 7: - return 'contiguous-file' + return 'contiguous-file'; case 72: return 'pax-header'; } @@ -78,7 +88,7 @@ var encodeOct = function(val, n) { }; var decodeOct = function(val, offset) { - return parseInt(val.slice(offset, indexOf(val, 32, offset)).toString(), 8); + return parseInt(val.slice(offset, clamp(indexOf(val, 32, offset), val.length, val.length)).toString(), 8); }; var decodeStr = function(val, offset) { diff --git a/pack.js b/pack.js index a4ad380..d43fd9d 100644 --- a/pack.js +++ b/pack.js @@ -3,6 +3,9 @@ var util = require('util'); var eos = require('end-of-stream'); var headers = require('./headers'); +var Readable = stream.Readable || require('readable-stream').Readable; +var Writable = stream.Writable || require('readable-stream').Writable; + var END_OF_TAR = new Buffer(1024); END_OF_TAR.fill(0); @@ -14,13 +17,13 @@ var overflow = function(self, size) { }; var Sink = function(to) { - stream.Writable.call(this); + Writable.call(this); this.written = 0; this._to = to; this._destroyed = false; }; -util.inherits(Sink, stream.Writable); +util.inherits(Sink, Writable); Sink.prototype._write = function(data, enc, cb) { this.written += data.length; @@ -36,7 +39,7 @@ Sink.prototype.destroy = function() { var Pack = function(opts) { if (!(this instanceof Pack)) return new Pack(opts); - stream.Readable.call(this, opts); + Readable.call(this, opts); this._drain = noop; this._finalized = false; @@ -45,7 +48,7 @@ var Pack = function(opts) { this._stream = null; }; -util.inherits(Pack, stream.Readable); +util.inherits(Pack, Readable); Pack.prototype.entry = function(header, buffer, callback) { if (this._stream) throw new Error('already piping an entry'); diff --git a/package.json b/package.json index c657a0e..58582d7 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,17 @@ "description": "tar-stream is a streaming tar parser and generator and nothing else. It is streams2 and operates purely using streams which means you can easily extract/parse tarballs without ever hitting the file system.", "repository": "git://github.com:mafintosh/tar-stream.git", "author": "Mathias Buus ", + "engines": { + "node": ">= 0.8.0" + }, "dependencies": { "end-of-stream": "~0.1.3", "bl": "~0.6.0" }, "devDependencies": { "tap": "~0.4.6", - "concat-stream": "~1.2.1" + "concat-stream": "~1.2.1", + "readable-stream": "~1.1.9" }, "scripts": { "test": "tap test/*.js" diff --git a/test/extract.js b/test/extract.js index 5f9f6db..6880cae 100644 --- a/test/extract.js +++ b/test/extract.js @@ -4,6 +4,16 @@ var fixtures = require('./fixtures'); var concat = require('concat-stream'); var fs = require('fs'); +var clamp = function(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +}; + test('one-file', function(t) { t.plan(3); @@ -76,7 +86,7 @@ test('chunked-one-file', function(t) { var b = fs.readFileSync(fixtures.ONE_FILE_TAR); for (var i = 0; i < b.length; i += 321) { - extract.write(b.slice(i, i+321)); + extract.write(b.slice(i, clamp(i+321, b.length, b.length))); } extract.end(); }); @@ -203,7 +213,7 @@ test('chunked-multi-file', function(t) { var b = fs.readFileSync(fixtures.MULTI_FILE_TAR); for (var i = 0; i < b.length; i += 321) { - extract.write(b.slice(i, i+321)); + extract.write(b.slice(i, clamp(i+321, b.length, b.length))); } extract.end(); });