diff --git a/headers.js b/headers.js index eeb2842..69f4439 100644 --- a/headers.js +++ b/headers.js @@ -2,6 +2,16 @@ var ZEROS = '0000000000000000000'; var ZERO_OFFSET = '0'.charCodeAt(0); var USTAR = 'ustar00'; +function clamp(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/test/extract.js b/test/extract.js index 5f9f6db..f40d060 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'); +function clamp(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(); });