Trigger an error if there is an incomplete entry at the end of stream (#83)
* Check if there is an incomplete entry at the end of the input An error will be raised if the last entry wans't complete. This will only work in node >= v8, since that's where _final() was introduced. Older node versions will ignore that function and will be unaffected. * Add padding at the end of gnu-long-path.tar This test case file was actually to short. The new code checking for unexpected end of file rejected it. Gnu tar agrees, it also failed to extract it with "Unexpected EOF in archive". * Added test case to check handling of incomplete data This tests that an error event is created when the input file is incomplete. * Check callback directly instead of passing extra parameter
This commit is contained in:
parent
c0b13f7329
commit
689d3fafd5
5 changed files with 30 additions and 0 deletions
|
@ -48,6 +48,7 @@ var Extract = function (opts) {
|
||||||
this._offset = 0
|
this._offset = 0
|
||||||
this._buffer = bl()
|
this._buffer = bl()
|
||||||
this._missing = 0
|
this._missing = 0
|
||||||
|
this._partial = false
|
||||||
this._onparse = noop
|
this._onparse = noop
|
||||||
this._header = null
|
this._header = null
|
||||||
this._stream = null
|
this._stream = null
|
||||||
|
@ -181,6 +182,7 @@ var Extract = function (opts) {
|
||||||
self._parse(header.size, onstreamend)
|
self._parse(header.size, onstreamend)
|
||||||
oncontinue()
|
oncontinue()
|
||||||
}
|
}
|
||||||
|
this._onheader = onheader
|
||||||
|
|
||||||
this._parse(512, onheader)
|
this._parse(512, onheader)
|
||||||
}
|
}
|
||||||
|
@ -200,6 +202,7 @@ Extract.prototype._parse = function (size, onparse) {
|
||||||
if (this._destroyed) return
|
if (this._destroyed) return
|
||||||
this._offset += size
|
this._offset += size
|
||||||
this._missing = size
|
this._missing = size
|
||||||
|
if (onparse === this._onheader) this._partial = false
|
||||||
this._onparse = onparse
|
this._onparse = onparse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +220,7 @@ Extract.prototype._write = function (data, enc, cb) {
|
||||||
var s = this._stream
|
var s = this._stream
|
||||||
var b = this._buffer
|
var b = this._buffer
|
||||||
var missing = this._missing
|
var missing = this._missing
|
||||||
|
if (data.length) this._partial = true
|
||||||
|
|
||||||
// we do not reach end-of-chunk now. just forward it
|
// we do not reach end-of-chunk now. just forward it
|
||||||
|
|
||||||
|
@ -246,4 +250,9 @@ Extract.prototype._write = function (data, enc, cb) {
|
||||||
this._onparse()
|
this._onparse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Extract.prototype._final = function (cb) {
|
||||||
|
if (this._partial) cb(new Error('unexpected end of data'))
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Extract
|
module.exports = Extract
|
||||||
|
|
|
@ -570,3 +570,23 @@ test('latin-1', function (t) { // can unpack filenames encoded in latin-1
|
||||||
|
|
||||||
extract.end(fs.readFileSync(fixtures.LATIN1_TAR))
|
extract.end(fs.readFileSync(fixtures.LATIN1_TAR))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('incomplete', function (t) {
|
||||||
|
t.plan(2)
|
||||||
|
|
||||||
|
var extract = tar.extract()
|
||||||
|
|
||||||
|
extract.on('entry', function (header, stream, callback) {
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.on('error', function (err) {
|
||||||
|
t.same(err.message, 'unexpected end of data')
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.on('finish', function () {
|
||||||
|
t.ok(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.end(fs.readFileSync(fixtures.INCOMPLETE_TAR))
|
||||||
|
})
|
||||||
|
|
BIN
test/fixtures/gnu-long-path.tar
vendored
BIN
test/fixtures/gnu-long-path.tar
vendored
Binary file not shown.
BIN
test/fixtures/incomplete.tar
vendored
Normal file
BIN
test/fixtures/incomplete.tar
vendored
Normal file
Binary file not shown.
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
|
@ -16,3 +16,4 @@ exports.LARGE_UID_GID = path.join(__dirname, 'large-uid-gid.tar')
|
||||||
exports.BASE_256_SIZE = path.join(__dirname, 'base-256-size.tar')
|
exports.BASE_256_SIZE = path.join(__dirname, 'base-256-size.tar')
|
||||||
exports.HUGE = path.join(__dirname, 'huge.tar.gz')
|
exports.HUGE = path.join(__dirname, 'huge.tar.gz')
|
||||||
exports.LATIN1_TAR = path.join(__dirname, 'latin1.tar')
|
exports.LATIN1_TAR = path.join(__dirname, 'latin1.tar')
|
||||||
|
exports.INCOMPLETE_TAR = path.join(__dirname, 'incomplete.tar')
|
||||||
|
|
Loading…
Reference in a new issue