support gnu long path. fixes #35

This commit is contained in:
Mathias Buus 2015-04-18 12:31:03 -07:00
parent 7c57165ad2
commit e8c8872952
5 changed files with 64 additions and 0 deletions

View file

@ -53,6 +53,8 @@ var Extract = function(opts) {
this._destroyed = false this._destroyed = false
this._pax = null this._pax = null
this._paxGlobal = null this._paxGlobal = null
this._gnuLongPath = null
this._gnuLongLinkPath = null
var self = this var self = this
var b = self._buffer var b = self._buffer
@ -96,6 +98,20 @@ var Extract = function(opts) {
onstreamend() onstreamend()
} }
var ongnulongpath = function() {
var size = self._header.size
this._gnuLongPath = headers.decodeLongPath(b.slice(0, size))
b.consume(size)
onstreamend()
}
var ongnulonglinkpath = function() {
var size = self._header.size
this._gnuLongLinkPath = headers.decodeLongPath(b.slice(0, size))
b.consume(size)
onstreamend()
}
var onheader = function() { var onheader = function() {
var offset = self._offset var offset = self._offset
var header var header
@ -111,6 +127,16 @@ var Extract = function(opts) {
oncontinue() oncontinue()
return return
} }
if (header.type === 'gnu-long-path') {
self._parse(header.size, ongnulongpath)
oncontinue()
return
}
if (header.type === 'gnu-long-link-path') {
self._parse(header.size, ongnulonglinkpath)
oncontinue()
return
}
if (header.type === 'pax-global-header') { if (header.type === 'pax-global-header') {
self._parse(header.size, onpaxglobalheader) self._parse(header.size, onpaxglobalheader)
oncontinue() oncontinue()
@ -122,6 +148,16 @@ var Extract = function(opts) {
return return
} }
if (self._gnuLongPath) {
header.name = self._gnuLongPath
self._gnuLongPath = null
}
if (self._gnuLongLinkPath) {
header.linkname = self._gnuLongLinkPath
self._gnuLongLinkPath = null
}
if (self._pax) { if (self._pax) {
self._header = header = mixinPax(header, self._pax) self._header = header = mixinPax(header, self._pax)
self._pax = null self._pax = null

View file

@ -34,6 +34,11 @@ var toType = function(flag) {
return 'pax-header' return 'pax-header'
case 55: case 55:
return 'pax-global-header' return 'pax-global-header'
case 27:
return 'gnu-long-link-path'
case 28:
case 30:
return 'gnu-long-path'
} }
return null return null
@ -110,6 +115,10 @@ var addLength = function(str) {
return (len+digits)+str return (len+digits)+str
} }
exports.decodeLongPath = function(buf) {
return decodeStr(buf, 0, buf.length)
}
exports.encodePax = function(opts) { // TODO: encode more stuff in pax exports.encodePax = function(opts) { // TODO: encode more stuff in pax
var result = '' var result = ''
if (opts.name) result += addLength(' path='+opts.name+'\n') if (opts.name) result += addLength(' path='+opts.name+'\n')

View file

@ -435,3 +435,21 @@ test('space prefixed', function(t) {
extract.end(fs.readFileSync(fixtures.SPACE_TAR_GZ)) extract.end(fs.readFileSync(fixtures.SPACE_TAR_GZ))
}) })
test('gnu long path', function(t) {
t.plan(2)
var extract = tar.extract()
extract.on('entry', function(header, stream, callback) {
t.ok(header.name.length > 100)
callback()
})
extract.on('finish', function() {
t.ok(true)
})
extract.end(fs.readFileSync(fixtures.GNU_LONG_PATH))
})

BIN
test/fixtures/gnu-long-path.tar vendored Normal file

Binary file not shown.

View file

@ -9,3 +9,4 @@ exports.UNICODE_TAR = path.join(__dirname, 'unicode.tar')
exports.NAME_IS_100_TAR = path.join(__dirname, 'name-is-100.tar') exports.NAME_IS_100_TAR = path.join(__dirname, 'name-is-100.tar')
exports.INVALID_TGZ = path.join(__dirname, 'invalid.tgz') exports.INVALID_TGZ = path.join(__dirname, 'invalid.tgz')
exports.SPACE_TAR_GZ = path.join(__dirname, 'space.tar') exports.SPACE_TAR_GZ = path.join(__dirname, 'space.tar')
exports.GNU_LONG_PATH = path.join(__dirname, 'gnu-long-path.tar')